برنامه نویسی

الگوریتم های رمزگشایی: Rabin-Karp – DEV Community

Summarize this content to 400 words in Persian Lang

رابین-کارپ چیست؟

Rabin-Karp یک الگوریتم جستجوی رشته ای کارآمد است که از هش برای یافتن الگوهای درون یک متن استفاده می کند. با مقایسه مقادیر هش رشته‌های فرعی، از مقایسه کاراکتر به کاراکتر در بیشتر موارد جلوگیری می‌کند. این رویکرد به‌ویژه برای جستجوهای الگوی چندگانه، که در آن الگوریتم هش‌ها را برای همه الگوها محاسبه می‌کند و آنها را در برابر یک متن به طور مؤثر بررسی می‌کند، مؤثر است.

نقطه قوت کلیدی Rabin-Karp در استفاده از تابع هش نورد است که امکان محاسبه مجدد سریع مقادیر هش را برای رشته های فرعی همپوشانی می دهد. با این حال، اگر برخورد هش به طور مکرر اتفاق بیفتد، عملکرد آن کاهش می‌یابد که نیاز به مقایسه کاراکترهای اضافی دارد.

نمای فنی

رابین-کارپ چگونه کار می کند

الگوریتم در دو فاز اصلی عمل می کند:

محاسبه هش:

هش الگو را محاسبه کنید.
هش اولین رشته فرعی (پنجره) را در متنی به طول الگو محاسبه کنید.

پنجره کشویی و تطبیق:

پنجره را هر بار یک کاراکتر در متن بلغزانید.
برای جلوگیری از محاسبه مجدد از ابتدا، هش را با استفاده از یک تابع هش نورد به روز کنید.
هش پنجره فعلی را با هش الگو مقایسه کنید. اگر مطابقت دارند، نویسه‌های واقعی را تأیید کنید تا مطابقت را تأیید کنید (برای رسیدگی به برخوردهای هش).

خلاصه یک دانش آموز کلاس پنجم

تصور کنید که به دنبال دست خط دوست خود در یک دسته کاغذ هستید. به جای خواندن هر کلمه، ابتدا ظاهر کلی مقاله (هش آن) را بررسی می کنید. اگر شبیه به نظر می رسد، برای تأیید، نگاه دقیق تری بیندازید. Rabin-Karp به شما اجازه می دهد تا مقالات را به طور موثر مرور کنید!

مثال دنیای واقعی

جستجوی توالی های DNA (الگوهای) در ژنوم (متن) را در نظر بگیرید. توانایی Rabin-Karp برای محاسبه هش برای الگوهای متعدد و مقایسه کارآمد آنها، آن را به انتخابی عالی برای این کار تبدیل می‌کند.

مثال هایی با کد، تکرارهای تفصیلی، و الگوهای بهینه شده

1. جستجوی تک الگو

مشکل: با استفاده از Rabin-Karp اولین رخداد یک الگو را در متن پیدا کنید.

کد:

public static int RabinKarp(string text, string pattern, int prime = 101)
{
int m = pattern.Length;
int n = text.Length;
int patternHash = 0, windowHash = 0, h = 1;

// Edge case: Pattern length > text length
if (m > n)
{
return -1; // Pattern cannot exist in the text
}

// Compute h = pow(256, m-1) % prime
for (int i = 0; i < m – 1; i++)
h = (h * 256) % prime;

// Compute the hash value for the pattern
for (int i = 0; i < m; i++)
{
patternHash = (256 * patternHash + pattern[i]) % prime;
}

// Compute the hash value for the first window of the text
for (int i = 0; i < m && i < n; i++)
{
windowHash = (256 * windowHash + text[i]) % prime;
}

// Slide the window across the text
for (int i = 0; i <= n – m; i++)
{
// Compare hash values
if (patternHash == windowHash)
{
// Confirm by comparing actual characters to handle hash collisions
if (text.Substring(i, m) == pattern)
return i; // Pattern found
}

// Compute the hash for the next window
if (i < n – m)
{
windowHash = (256 * (windowHash – text[i] * h) + text[i + m]) % prime;

// Ensure non-negative hash values
if (windowHash < 0)
windowHash += prime;
}
}

return -1; // Pattern not found
}

// Example Usage
string text = “ababcababc”;
string pattern = “abc”;
Console.WriteLine(RabinKarp(text, pattern)); // Output: 2

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

آنچه در هر تکرار اتفاق می افتد:

Hash Initialization:

محاسبه کنید patternHash برای «abc»: (25643).
محاسبه کنید windowHash برای «ابا»: (25642).

مقایسه پنجره اول:

(windowHash \neq patternHash). پنجره را بلغزانید.

مقایسه پنجره دوم:

به روز رسانی windowHash به (25643). (windowHash = patternHash).
کاراکترهای واقعی را تأیید کنید: “abc” در نمایه (2) مطابقت دارد.

مقایسه های بعدی:

به لغزش پنجره تا انتهای متن ادامه دهید.

2. جستجوی الگوهای چندگانه

مشکل: وقوع الگوهای متعدد را در یک متن پیدا کنید.

کد:

public static List<int> RabinKarpMulti(string text, List<string> patterns, int prime = 101)
{
var result = new List<int>();
foreach (var pattern in patterns)
{
int index = RabinKarp(text, pattern, prime);
result.Add(index);
}
return result;
}

// Example Usage
string text = “ababcababc”;
List<string> patterns = new List<string> { “abc”, “ab” };
List<int> results = RabinKarpMulti(text, patterns);
Console.WriteLine(string.Join(“, “, results)); // Output: 2, 0

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

چه اتفاقی می افتد:

هش را برای هر الگو (“abc”، “ab”) محاسبه کنید.
برای هر الگو از تابع Rabin-Karp استفاده کنید و شاخص های مربوطه را برگردانید.

3. رولینگ هش تظاهرات

مشکل: کارایی هش نورد را نشان دهید.

کد:

public static void RollingHashDemo()
{
string text = “abcd”;
int prime = 101;
int windowHash = 0, h = 1;

// Compute h = pow(256, m-1) % prime
for (int i = 0; i < 2; i++) h = (h * 256) % prime;

// Compute initial hash for “ab”
windowHash = (256 * ‘a’ + ‘b’) % prime;
Console.WriteLine($”Initial Hash: {windowHash}”);

// Slide the window to “bc”
windowHash = (256 * (windowHash – ‘a’ * h) + ‘c’) % prime;
if (windowHash < 0) windowHash += prime;
Console.WriteLine($”New Hash: {windowHash}”);
}

// Example Usage
RollingHashDemo();
// Output:
// Initial Hash: 84
// New Hash: 38

وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

آنچه در هر تکرار اتفاق می افتد:

هش اولیه را برای “ab” محاسبه کنید: (84).
هش را برای “bc” با استفاده از هش نورد به روز کنید: (38).

نتیجه گیری

الگوریتم Rabin-Karp در سناریوهایی می درخشد که در آن جستجوهای الگوی متعدد مورد نیاز است یا زمانی که هش کارآمد می تواند مقایسه کاراکترها را به حداقل برساند. با اجرای اصلاح شده، محاسبات هش برای الگوها و پنجره های متنی اکنون از هم جدا شده اند و وضوح و استحکام را تضمین می کنند.

تسلط بر Rabin-Karp پایه ای قوی برای درک هش در طراحی الگوریتم فراهم می کند و شما را برای مقابله با چالش های پیچیده تطبیق الگو آماده می کند!

رابین-کارپ چیست؟

Rabin-Karp یک الگوریتم جستجوی رشته ای کارآمد است که از هش برای یافتن الگوهای درون یک متن استفاده می کند. با مقایسه مقادیر هش رشته‌های فرعی، از مقایسه کاراکتر به کاراکتر در بیشتر موارد جلوگیری می‌کند. این رویکرد به‌ویژه برای جستجوهای الگوی چندگانه، که در آن الگوریتم هش‌ها را برای همه الگوها محاسبه می‌کند و آنها را در برابر یک متن به طور مؤثر بررسی می‌کند، مؤثر است.

نقطه قوت کلیدی Rabin-Karp در استفاده از تابع هش نورد است که امکان محاسبه مجدد سریع مقادیر هش را برای رشته های فرعی همپوشانی می دهد. با این حال، اگر برخورد هش به طور مکرر اتفاق بیفتد، عملکرد آن کاهش می‌یابد که نیاز به مقایسه کاراکترهای اضافی دارد.


نمای فنی


رابین-کارپ چگونه کار می کند

الگوریتم در دو فاز اصلی عمل می کند:

  1. محاسبه هش:

    • هش الگو را محاسبه کنید.
    • هش اولین رشته فرعی (پنجره) را در متنی به طول الگو محاسبه کنید.
  2. پنجره کشویی و تطبیق:

    • پنجره را هر بار یک کاراکتر در متن بلغزانید.
    • برای جلوگیری از محاسبه مجدد از ابتدا، هش را با استفاده از یک تابع هش نورد به روز کنید.
    • هش پنجره فعلی را با هش الگو مقایسه کنید. اگر مطابقت دارند، نویسه‌های واقعی را تأیید کنید تا مطابقت را تأیید کنید (برای رسیدگی به برخوردهای هش).

خلاصه یک دانش آموز کلاس پنجم

تصور کنید که به دنبال دست خط دوست خود در یک دسته کاغذ هستید. به جای خواندن هر کلمه، ابتدا ظاهر کلی مقاله (هش آن) را بررسی می کنید. اگر شبیه به نظر می رسد، برای تأیید، نگاه دقیق تری بیندازید. Rabin-Karp به شما اجازه می دهد تا مقالات را به طور موثر مرور کنید!


مثال دنیای واقعی

جستجوی توالی های DNA (الگوهای) در ژنوم (متن) را در نظر بگیرید. توانایی Rabin-Karp برای محاسبه هش برای الگوهای متعدد و مقایسه کارآمد آنها، آن را به انتخابی عالی برای این کار تبدیل می‌کند.


مثال هایی با کد، تکرارهای تفصیلی، و الگوهای بهینه شده


1. جستجوی تک الگو

مشکل: با استفاده از Rabin-Karp اولین رخداد یک الگو را در متن پیدا کنید.

کد:

public static int RabinKarp(string text, string pattern, int prime = 101)
{
    int m = pattern.Length;
    int n = text.Length;
    int patternHash = 0, windowHash = 0, h = 1;

    // Edge case: Pattern length > text length
    if (m > n)
    {
        return -1; // Pattern cannot exist in the text
    }

    // Compute h = pow(256, m-1) % prime
    for (int i = 0; i < m - 1; i++)
        h = (h * 256) % prime;

    // Compute the hash value for the pattern
    for (int i = 0; i < m; i++)
    {
        patternHash = (256 * patternHash + pattern[i]) % prime;
    }

    // Compute the hash value for the first window of the text
    for (int i = 0; i < m && i < n; i++)
    {
        windowHash = (256 * windowHash + text[i]) % prime;
    }

    // Slide the window across the text
    for (int i = 0; i <= n - m; i++)
    {
        // Compare hash values
        if (patternHash == windowHash)
        {
            // Confirm by comparing actual characters to handle hash collisions
            if (text.Substring(i, m) == pattern)
                return i; // Pattern found
        }

        // Compute the hash for the next window
        if (i < n - m)
        {
            windowHash = (256 * (windowHash - text[i] * h) + text[i + m]) % prime;

            // Ensure non-negative hash values
            if (windowHash < 0)
                windowHash += prime;
        }
    }

    return -1; // Pattern not found
}

// Example Usage
string text = "ababcababc";
string pattern = "abc";
Console.WriteLine(RabinKarp(text, pattern)); // Output: 2
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

آنچه در هر تکرار اتفاق می افتد:

  1. Hash Initialization:

    • محاسبه کنید patternHash برای «abc»: (25643).
    • محاسبه کنید windowHash برای «ابا»: (25642).
  2. مقایسه پنجره اول:

    • (windowHash \neq patternHash). پنجره را بلغزانید.
  3. مقایسه پنجره دوم:

    • به روز رسانی windowHash به (25643). (windowHash = patternHash).
    • کاراکترهای واقعی را تأیید کنید: “abc” در نمایه (2) مطابقت دارد.
  4. مقایسه های بعدی:

    • به لغزش پنجره تا انتهای متن ادامه دهید.

2. جستجوی الگوهای چندگانه

مشکل: وقوع الگوهای متعدد را در یک متن پیدا کنید.

کد:

public static List<int> RabinKarpMulti(string text, List<string> patterns, int prime = 101)
{
    var result = new List<int>();
    foreach (var pattern in patterns)
    {
        int index = RabinKarp(text, pattern, prime);
        result.Add(index);
    }
    return result;
}

// Example Usage
string text = "ababcababc";
List<string> patterns = new List<string> { "abc", "ab" };
List<int> results = RabinKarpMulti(text, patterns);
Console.WriteLine(string.Join(", ", results)); // Output: 2, 0
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

چه اتفاقی می افتد:

  1. هش را برای هر الگو (“abc”، “ab”) محاسبه کنید.
  2. برای هر الگو از تابع Rabin-Karp استفاده کنید و شاخص های مربوطه را برگردانید.

3. رولینگ هش تظاهرات

مشکل: کارایی هش نورد را نشان دهید.

کد:

public static void RollingHashDemo()
{
    string text = "abcd";
    int prime = 101;
    int windowHash = 0, h = 1;

    // Compute h = pow(256, m-1) % prime
    for (int i = 0; i < 2; i++) h = (h * 256) % prime;

    // Compute initial hash for "ab"
    windowHash = (256 * 'a' + 'b') % prime;
    Console.WriteLine($"Initial Hash: {windowHash}");

    // Slide the window to "bc"
    windowHash = (256 * (windowHash - 'a' * h) + 'c') % prime;
    if (windowHash < 0) windowHash += prime;
    Console.WriteLine($"New Hash: {windowHash}");
}

// Example Usage
RollingHashDemo();
// Output:
// Initial Hash: 84
// New Hash: 38
وارد حالت تمام صفحه شوید

از حالت تمام صفحه خارج شوید

آنچه در هر تکرار اتفاق می افتد:

  1. هش اولیه را برای “ab” محاسبه کنید: (84).
  2. هش را برای “bc” با استفاده از هش نورد به روز کنید: (38).

نتیجه گیری

الگوریتم Rabin-Karp در سناریوهایی می درخشد که در آن جستجوهای الگوی متعدد مورد نیاز است یا زمانی که هش کارآمد می تواند مقایسه کاراکترها را به حداقل برساند. با اجرای اصلاح شده، محاسبات هش برای الگوها و پنجره های متنی اکنون از هم جدا شده اند و وضوح و استحکام را تضمین می کنند.

تسلط بر Rabin-Karp پایه ای قوی برای درک هش در طراحی الگوریتم فراهم می کند و شما را برای مقابله با چالش های پیچیده تطبیق الگو آماده می کند!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا