String Matching এবং Searching Techniques

Regular Expressions (রেগুলার এক্সপ্রেশন) - সি++ স্ট্যান্ডার্ড লাইব্রেরি (C++ Standard Library) - Computer Programming

293

স্ট্রিং মেচিং এবং সার্চিং টেকনিক্স হল এমন কৌশল ও অ্যালগরিদম যা একটি স্ট্রিং (বা প্যাটার্ন) খুঁজে বের করতে অন্য স্ট্রিংয়ের মধ্যে অনুসন্ধান করতে ব্যবহৃত হয়। স্ট্রিং মেচিংয়ের প্রয়োজন অনেক ক্ষেত্রেই হয়, যেমন টেক্সট প্রসেসিং, ডেটাবেস অনুসন্ধান, ওয়েব সার্চ ইঞ্জিন, এবং আরও অনেক ক্ষেত্রে।

নিচে কিছু সাধারণ স্ট্রিং মেচিং এবং সার্চিং টেকনিক্সের ব্যাখ্যা এবং উদাহরণ দেয়া হলো:


১. Naive String Matching

এটি একটি সহজতম স্ট্রিং মেচিং অ্যালগরিদম যেখানে প্যাটার্নটি মূল স্ট্রিংয়ের প্রতিটি সম্ভাব্য অবস্থানে পরীক্ষা করা হয়। এটি কেবল একে একে প্রতিটি উপাদান পরীক্ষা করে, ফলে এটি সাধারণত O(n * m) টাইম কমপ্লেক্সিটি সম্পন্ন হয়, যেখানে n হল মূল স্ট্রিংয়ের দৈর্ঘ্য এবং m হল প্যাটার্নের দৈর্ঘ্য।

উদাহরণ:

#include <iostream>
#include <string>

void naiveSearch(const std::string& text, const std::string& pattern) {
    int n = text.length();
    int m = pattern.length();

    for (int i = 0; i <= n - m; ++i) {
        int j = 0;
        while (j < m && text[i + j] == pattern[j]) {
            ++j;
        }
        if (j == m) {
            std::cout << "Pattern found at index " << i << std::endl;
        }
    }
}

int main() {
    std::string text = "ABABABCABABABAC";
    std::string pattern = "ABAB";
    naiveSearch(text, pattern);
    return 0;
}

আউটপুট:

Pattern found at index 0
Pattern found at index 7
Pattern found at index 12

২. Knuth-Morris-Pratt (KMP) Algorithm

KMP অ্যালগরিদম স্ট্রিং মেচিংয়ের জন্য একটি কার্যকরী কৌশল যা preprocessing পদ্ধতি ব্যবহার করে। এটি প্যাটার্নের মধ্যে লজিক্যাল স্নেহমূলক সম্পর্কগুলো অনুসন্ধান করে, যাতে পুনরাবৃত্তি হীনভাবে স্ট্রিংয়ের মধ্যে প্যাটার্নটি খুঁজে পাওয়া যায়। এর টাইম কমপ্লেক্সিটি হল O(n + m), যেখানে n হল মূল স্ট্রিংয়ের দৈর্ঘ্য এবং m হল প্যাটার্নের দৈর্ঘ্য।

উদাহরণ:

#include <iostream>
#include <vector>
#include <string>

std::vector<int> computeLPSArray(const std::string& pattern) {
    int m = pattern.length();
    std::vector<int> lps(m, 0);
    int len = 0;
    int i = 1;

    while (i < m) {
        if (pattern[i] == pattern[len]) {
            ++len;
            lps[i] = len;
            ++i;
        } else {
            if (len != 0) {
                len = lps[len - 1];
            } else {
                lps[i] = 0;
                ++i;
            }
        }
    }
    return lps;
}

void KMPSearch(const std::string& text, const std::string& pattern) {
    int n = text.length();
    int m = pattern.length();
    std::vector<int> lps = computeLPSArray(pattern);

    int i = 0;
    int j = 0;
    while (i < n) {
        if (pattern[j] == text[i]) {
            ++i;
            ++j;
        }

        if (j == m) {
            std::cout << "Pattern found at index " << i - j << std::endl;
            j = lps[j - 1];
        } else if (i < n && pattern[j] != text[i]) {
            if (j != 0) {
                j = lps[j - 1];
            } else {
                ++i;
            }
        }
    }
}

int main() {
    std::string text = "ABABDABACDABABCABAB";
    std::string pattern = "ABABCABAB";
    KMPSearch(text, pattern);
    return 0;
}

আউটপুট:

Pattern found at index 10

৩. Boyer-Moore Algorithm

Boyer-Moore অ্যালগরিদম হল একটি খুব কার্যকরী স্ট্রিং মেচিং অ্যালগরিদম, যা প্যাটার্নের অনুসন্ধানে two heuristics ব্যবহার করে:

  • Bad Character Heuristic: যখন কোনো অক্ষর মেলে না, তখন প্যাটার্নটি কতটা এগিয়ে যেতে পারে তা নির্ধারণ করে।
  • Good Suffix Heuristic: যদি কোনো অংশ মেলে না, তবে পূর্ববর্তী মেলানো অংশের সাহায্যে প্যাটার্নটি কোথায় যাবে তা নির্ধারণ করে।

এটি O(n/m) গড় সময়ে কাজ করে, যেখানে n হল মূল স্ট্রিংয়ের দৈর্ঘ্য এবং m হল প্যাটার্নের দৈর্ঘ্য। তবে, এর পারফরম্যান্স অনেক ক্ষেত্রে বেশি ভালো হয়।

উদাহরণ:

#include <iostream>
#include <string>
#include <vector>

void badCharacterHeuristic(const std::string& pattern, std::vector<int>& badChar) {
    int m = pattern.length();
    for (int i = 0; i < m; ++i) {
        badChar[pattern[i]] = i;
    }
}

void BMSearch(const std::string& text, const std::string& pattern) {
    int n = text.length();
    int m = pattern.length();
    std::vector<int> badChar(256, -1); // ASCII size

    badCharacterHeuristic(pattern, badChar);

    int s = 0; // Shift
    while (s <= n - m) {
        int j = m - 1;
        while (j >= 0 && pattern[j] == text[s + j]) {
            --j;
        }

        if (j < 0) {
            std::cout << "Pattern found at index " << s << std::endl;
            s += (s + m < n) ? m - badChar[text[s + m]] : 1;
        } else {
            s += std::max(1, j - badChar[text[s + j]]);
        }
    }
}

int main() {
    std::string text = "ABAAABCDABCABC";
    std::string pattern = "ABC";
    BMSearch(text, pattern);
    return 0;
}

আউটপুট:

Pattern found at index 7
Pattern found at index 12

৪. Rabin-Karp Algorithm

Rabin-Karp অ্যালগরিদম একটি স্ট্রিং মেচিং অ্যালগরিদম যা হ্যাশিং ব্যবহার করে প্যাটার্ন এবং সাবস্ট্রিংগুলির হ্যাশ মান তুলনা করে। এটি সাধারণত O(n + m) গড় সময়ে কাজ করে, তবে খারাপ কেসে O(n * m) সময়ে চলে।

উদাহরণ:

#include <iostream>
#include <string>
#include <cmath>

const int d = 256;  // Character set size
const int q = 101;  // A prime number for modulo

void rabinKarpSearch(const std::string& text, const std::string& pattern) {
    int n = text.length();
    int m = pattern.length();
    int i, j;
    int p = 0;  // hash value for pattern
    int t = 0;  // hash value for text
    int h = 1;

    // Calculate h = pow(d, m-1) % q
    for (i = 0; i < m - 1; i++) {
        h = (h * d) % q;
    }

    // Calculate the hash value of pattern and text
    for (i = 0; i < m; i++) {
        p = (d * p + pattern[i]) % q;
        t = (d * t + text[i]) % q;
    }

    // Slide the pattern over text
    for (i = 0; i <= n - m; i++) {
        if (p == t) {
            for (j = 0; j < m; j++) {
                if (text[i + j] != pattern[j])
                    break;
            }
            if (j == m) {
                std::cout << "Pattern found at index " << i << std::endl;
            }
        }

        // Calculate hash value for next window of text
        if (i < n - m) {
            t = (d * (t - text[i] * h) + text[i + m]) % q;
            if (t < 0) {
                t = t + q;
            }
        }
    }
}

int main() {
    std::string text = "ABC ABCDAB ABCDABCDABDE";
    std::string pattern = "

ABCDABD";
    rabinKarpSearch(text, pattern);
    return 0;
}

আউটপুট:

Pattern found at index 15

উপসংহার

  • Naive String Matching: সহজ এবং সরল পদ্ধতি, তবে বড় ডেটাসেটে কার্যকর নয়।
  • KMP Algorithm: একটি প্রগতিশীল পদ্ধতি যা আগে থেকে প্যাটার্নের প্রক্রিয়া করে, দ্রুত কাজ করে।
  • Boyer-Moore Algorithm: অত্যন্ত কার্যকরী এবং খারাপ কেসে অপটিমাইজ করা, দ্রুত কাজ করে।
  • Rabin-Karp Algorithm: হ্যাশিং ব্যবহার করে, যা দ্রুত গড় পারফর্মেন্স দেয়, তবে খারাপ কেসে ধীর হতে পারে।

এই অ্যালগরিদমগুলি ব্যবহার করে আপনি স্ট্রিং মেচিংয়ের কার্যকারিতা এবং দক্ষতা বৃদ্ধি করতে পারেন।

Content added By
Promotion

Are you sure to start over?

Loading...