জাভা: স্ট্রিং-এ শব্দ সংঘটনের সংখ্যা গণনা

ভূমিকা

একটি স্ট্রিংয়ে শব্দ সংঘটনের সংখ্যা গণনা করা একটি মোটামুটি সহজ কাজ, কিন্তু এটি করার জন্য বিভিন্ন পদ্ধতি রয়েছে। আপনাকে পদ্ধতিটির দক্ষতার জন্যও অ্যাকাউন্ট করতে হবে, যেহেতু আপনি সাধারণত স্বয়ংক্রিয় সরঞ্জামগুলি নিয়োগ করতে চান যখন আপনি কায়িক শ্রম সম্পাদন করতে চান না – অর্থাৎ যখন অনুসন্ধানের স্থান বড় হয়।

এই নির্দেশিকাটিতে, আপনি শিখবেন কিভাবে জাভাতে একটি স্ট্রিংয়ে শব্দ সংঘটনের সংখ্যা গণনা করতে হয়:

String searchText = "Your body may be chrome, but the heart never changes. It wants what it wants.";
String targetWord = "wants";

আমরা এর ঘটনার সংখ্যা অনুসন্ধান করব targetWord, ব্যবহার String.split(), Collections.frequency() এবং নিয়মিত অভিব্যক্তি।

এর সাথে স্ট্রিং-এ শব্দের ঘটনা গণনা করুন String.split()

একটি স্ট্রিংয়ে একটি টার্গেট শব্দের উপস্থিতি গণনা করার সবচেয়ে সহজ উপায় হল প্রতিটি শব্দের স্ট্রিংকে বিভক্ত করা এবং অ্যারের মাধ্যমে পুনরাবৃত্তি করা, একটি বৃদ্ধি করে wordCount প্রতিটি ম্যাচে। লক্ষ্য করুন যে যখন একটি শব্দের চারপাশে কোন ধরণের যতিচিহ্ন থাকে, যেমন wants. বাক্যের শেষে – সহজ শব্দ-স্তরের বিভাজন সঠিকভাবে আচরণ করবে wants এবং wants. পৃথক শব্দ হিসাবে!

এটিকে ঘিরে কাজ করার জন্য, আপনি সহজেই বাক্য থেকে সমস্ত বিরামচিহ্ন মুছে ফেলতে পারেন আগে এটি বিভক্ত করা:

String[] words = searchText.replaceAll("p{Punct}", "").split(" ");

int wordCount = 0;
for (int i=0; i < words.length; i++)
    if (words[i].equals(targetWord))
        wordCount++;
System.out.println(wordCount);

মধ্যে for লুপ, আমরা কেবল অ্যারের মাধ্যমে পুনরাবৃত্তি করি, প্রতিটি সূচকের উপাদান সমান কিনা তা পরীক্ষা করে দেখি targetWord. যদি এটা হয়, আমরা বৃদ্ধি wordCount, যা সম্পাদনের শেষে প্রিন্ট করে:

2

এর সাথে স্ট্রিং-এ শব্দের ঘটনা গণনা করুন Collections.frequency()

সার্জারির Collections.frequency() পদ্ধতি একটি অনেক পরিষ্কার, উচ্চ-স্তরের বাস্তবায়ন প্রদান করে, যা একটি সাধারণকে বিমূর্ত করে দেয় for লুপ, এবং উভয় পরিচয়ের জন্য পরীক্ষা করে (একটি বস্তু কিনা is অন্য বস্তু) এবং সমতা (একটি বস্তু অন্য বস্তুর সমান কিনা, সেই বস্তুর গুণগত বৈশিষ্ট্যের উপর নির্ভর করে)।

সার্জারির frequency() পদ্ধতি অনুসন্ধানের জন্য একটি তালিকা গ্রহণ করে, এবং লক্ষ্যবস্তু, এবং অন্যান্য সমস্ত বস্তুর জন্যও কাজ করে, যেখানে আচরণটি বস্তুটি নিজেই কীভাবে প্রয়োগ করে তার উপর নির্ভর করে। equals(). স্ট্রিং এর ক্ষেত্রে, equals() জন্য চেক স্ট্রিং এর বিষয়বস্তু:


searchText = searchText.replaceAll("p{Punct}", "");

int wordCount = Collections.frequency(Arrays.asList(searchText.split(" ")), targetWord);
System.out.println(wordCount);

এখানে, আমরা থেকে প্রাপ্ত অ্যারে রূপান্তর করেছি split() একটি জাভা মধ্যে ArrayListসাহায্যকারী ব্যবহার করে asList() পদ্ধতি Arrays ক্লাস হ্রাস অপারেশন frequency() এর ফ্রিকোয়েন্সি নির্দেশ করে একটি পূর্ণসংখ্যা প্রদান করে targetWord তালিকায়, এবং ফলাফল:

2

সঙ্গে স্ট্রিং মধ্যে শব্দ ঘটনা ম্যাচার (রেগুলার এক্সপ্রেশন – RegEx)

অবশেষে, আপনি নিদর্শন অনুসন্ধান করতে নিয়মিত এক্সপ্রেশন ব্যবহার করতে পারেন, এবং মিলিত নিদর্শনগুলির সংখ্যা গণনা করতে পারেন। এর জন্য রেগুলার এক্সপ্রেশন তৈরি করা হয়, তাই এটি কাজের জন্য খুবই স্বাভাবিক। জাভাতে, দ Pattern ক্লাস রেগুলার এক্সপ্রেশন উপস্থাপন এবং কম্পাইল করতে ব্যবহৃত হয়, এবং Matcher ক্লাস প্যাটার্ন খুঁজে পেতে এবং মেলাতে ব্যবহৃত হয়।

RegEx ব্যবহার করে, আমরা এক্সপ্রেশনের মধ্যেই বিরাম চিহ্নের পরিবর্তন কোড করতে পারি, তাই স্ট্রিংটিকে বাহ্যিকভাবে ফর্ম্যাট করার বা বিরাম চিহ্ন মুছে ফেলার কোন প্রয়োজন নেই, যা বড় টেক্সটের জন্য পছন্দনীয় যেখানে মেমরিতে অন্য পরিবর্তিত সংস্করণ সংরক্ষণ করা ব্যয়বহুল হতে পারে:

Pattern pattern = Pattern.compile("b%s(?!w)".format(targetWord));

Pattern pattern = Pattern.compile("bwants(?!w)");
Matcher matcher = pattern.matcher(searchText);

int wordCount = 0;
while (matcher.find())
    wordCount++;

System.out.println(wordCount);

এর ফলেও:

2

দক্ষতার মানদণ্ড

সুতরাং, কোনটি সবচেয়ে কার্যকর? আসুন একটি ছোট বেঞ্চমার্ক চালাই:

int runs = 100000;

long start1 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    int result = countOccurencesWithSplit(searchText, targetWord);
}

long end1 = System.currentTimeMillis();
System.out.println(String.format("Array split approach took: %s miliseconds", end1-start1));

long start2 = System.currentTimeMillis();
  for (int i = 0; i < runs; i++) {
    int result = countOccurencesWithCollections(searchText, targetWord);
}

long end2 = System.currentTimeMillis();
System.out.println(String.format("Collections.frequency() approach took: %s miliseconds", end2-start2));

long start3 = System.currentTimeMillis();
for (int i = 0; i < runs; i++) {
    int result = countOccurencesWithRegex(searchText, targetWord);
}

long end3 = System.currentTimeMillis();
System.out.println(String.format("Regex approach took: %s miliseconds", end3-start3));

প্রতিটি পদ্ধতি 100000 বার চালানো হবে (সংখ্যা যত বেশি হবে, বড় সংখ্যার আইনের কারণে সম্ভাবনার কারণে পার্থক্য এবং ফলাফল কম হবে)। এই কোড চালানোর ফলে:

Array split approach took: 152 miliseconds
Collections.frequency() approach took: 140 miliseconds
Regex approach took: 92 miliseconds

যাইহোক – যদি আমরা অনুসন্ধানটিকে আরও বড় করে গণনামূলকভাবে ব্যয়বহুল করে তুলি তাহলে কী হবে? আসুন একটি সিন্থেটিক বাক্য তৈরি করি:

List possibleWords = Arrays.asList("hello", "world ");
StringBuffer searchTextBuffer = new StringBuffer();

for (int i = 0; i < 100; i++) {
    searchTextBuffer.append(String.join(" ", possibleWords));
}
System.out.println(searchTextBuffer);

এটি বিষয়বস্তু সহ একটি স্ট্রিং তৈরি করে:

hello world hello world hello world hello ...

সেরা-অভ্যাস, শিল্প-স্বীকৃত মান এবং অন্তর্ভুক্ত চিট শীট সহ গিট শেখার জন্য আমাদের হ্যান্ডস-অন, ব্যবহারিক গাইড দেখুন। গুগলিং গিট কমান্ড এবং আসলে বন্ধ করুন শেখা এটা!

এখন, যদি আমরা "হ্যালো" বা "ওয়ার্ল্ড" এর জন্য অনুসন্ধান করি - তবে আগের দুটির চেয়ে অনেক বেশি মিল থাকবে। বেঞ্চমার্কে এখন আমাদের পদ্ধতিগুলি কীভাবে করবেন?

Array split approach took: 606 miliseconds
Collections.frequency() approach took: 899 miliseconds
Regex approach took: 801 miliseconds

এখন, অ্যারে বিভাজন দ্রুততম বেরিয়ে আসে! সাধারণভাবে, বেঞ্চমার্ক বিভিন্ন কারণের উপর নির্ভর করে - যেমন অনুসন্ধান স্থান, লক্ষ্য শব্দ, ইত্যাদি এবং আপনার ব্যক্তিগত ব্যবহারের ক্ষেত্রে বেঞ্চমার্ক থেকে ভিন্ন হতে পারে।

উপদেশ: আপনার নিজের পাঠ্যে পদ্ধতিগুলি ব্যবহার করে দেখুন, সময়গুলি নোট করুন এবং আপনার জন্য সবচেয়ে কার্যকর এবং মার্জিত একটি বেছে নিন।

উপসংহার

এই সংক্ষিপ্ত নির্দেশিকায়, আমরা জাভাতে একটি স্ট্রিং-এ একটি টার্গেট শব্দের জন্য শব্দ সংঘটন গণনা করার উপায় দেখেছি। আমরা স্ট্রিংটি বিভক্ত করে এবং একটি সাধারণ কাউন্টার ব্যবহার করে শুরু করেছি, তারপরে ব্যবহার করে Collections সহায়ক ক্লাস, এবং অবশেষে, নিয়মিত এক্সপ্রেশন ব্যবহার করে।

শেষ পর্যন্ত, আমরা পদ্ধতিগুলি বেঞ্চমার্ক করেছি, এবং লক্ষ্য করেছি যে কর্মক্ষমতা রৈখিক নয় এবং অনুসন্ধান স্থানের উপর নির্ভর করে৷ অনেকগুলি মিল সহ দীর্ঘতর ইনপুট পাঠ্যের জন্য, বিভক্ত অ্যারেগুলি সবচেয়ে কার্যকর বলে মনে হয়৷ তিনটি পদ্ধতি নিজেই চেষ্টা করুন এবং সবচেয়ে কার্যকরী একটি বেছে নিন।

সময় স্ট্যাম্প:

থেকে আরো Stackabuse