موضوع مقاله: الگوریتم جستجوی رشته رابین-کارپ | مخاطب: عمومی | لحن: دانشنامه‌ای | ساختار: عنوان، مقدمه، 3 بخش، جمع‌بندی | مقاله: | # الگوریتم جستجوی رشته رابین-کارپ | مقدمه: الگوریتم جستجوی رشتهٔ رابین-کارپ یکی از الگوریتم‌های تطابق رشته است که در سال 1987 توسط مایکل او. | ## بخش 1: الگوریتم جستجوی رشته رابین-کارپ | از این الگوریتم برای پیدا کردن مجموعه‌ای از رشته‌ها (الگوهاpatterns) در یک متن با به‌کارگیری درهم‌سازی استفاده می‌شود. جستجو با استفاده از شیفت دادن زیررشته در صورتی که متنی به طول n به صورت [T[1..n و رشته‌ای به طول m به صورت [P[1..m داشته باشیم که ، آسان‌ترین و ناکارآمدترین راه برای جستجو، الگوریتم جستجوی رشتهٔ ساده‌لوحانه است که همه حالت‌های ممکن را به این صورت بررسی می‌کند: در هر مرحله رشته [P[1..m با زیررشته‌ای از متن T مقایسه می‌گردد. زیررشته موردنظر در مرحله اول m حرف اول از متن T[1..m)، در مرحله دوم m حرف دوم از متن T[2..m+1) و به همین ترتیب در مرحله s ام m حرف s ام از متن T[s+1..s+m) می‌باشد. در این مقایسه‌ها، هر بار که دو رشتۀ مقایسه‌شده یکسان باشند، نشانگر یک‌بار رخ‌دادن رشته P در متن T است. الگوریتم رابین-کارپ سعی دارد با به‌کارگیری تابع درهم‌سازی، سرعت مقایسۀ رشتۀ الگو و زیررشته‌های متن را افزایش داده و از این طریق زمان اجرا را بهبود ببخشد. استفاده از درهم‌سازی یک تابع درهم‌سازی، تابعی است که مجموعۀ بزرگی از داده‌ها را به مجموعۀ کوچکتری از داده‌ها نگاشت می‌کند. در اینجا تابع درهم‌سازی هر رشته را به یک مقدار عددی که به آن مقدار درهم‌سازی می‌گویند، تبدیل می‌کند. الگوریتم رابین-کارپ با بهره‌گیری از این حقیقت که اگر دو رشته یکسان باشند، مقدار درهم‌سازی آن‌ها نیز با هم برابر خواهد بود، سعی دارد به جای مقایسه حرف یه حرف دو رشته، مقادیر درهم‌سازی آنان را مقایسه کند. | ## بخش 2: الگوریتم جستجوی رشته رابین-کارپ | برای این کار کافی است مقدار درهم‌سازی رشته الگو را حساب نماید و سپس در متن به دنبال زیررشته‌ای با مقدار درهم‌سازی برابر با آن بگردد. نکته‌ای که باید به آن توجه کرد این است که رشته‌های مختلف می‌توانند مقادیر درهم‌سازی یکسان داشته باشند. پس با اینکه یکسان بودن دو رشته به معنای یکسان بودن مقدار درهم‌سازی آنان است اما عکس این موضوع لزوماً برقرار نیست. در نتیجه در صورت برابر نبودن مقدار درهم‌سازی رشتۀ الگو و زیررشته قطعاً می‌توان نتیجه گرفت که خود رشته‌ها نیز با هم برابر نیستند ولی در صورت برابر بودن این دو مقدار لزوماً نمی‌توان برابری رشته‌ها را نتیجه گرفت (برابری مقدار درهم‌سازی شرط لازم است ولی کافی نیست و ممکن است دو رشته با مقدار درهم‌سازی برابر یافت کرده باشیم در حالی که اصل رشته‌ها برابر نیستند). پس در این حالت یکسان بودن زیررشته با رشتۀ الگو را باید با مقایسه حرف به حرف تحقیق کنیم. حال درصورتی که واقعاً تصادم رخ داده باشد (به رشته‌های متفاوت با مقدار درهم‌سازی یکسان برخورد کرده باشیم) این کار زمان اجرا را بیهوده افزایش داده است. خوشبختانه اگر تابع درهم‌سازی را خوب تعریف کنیم می‌توانیم امیدوار باشیم این رویداد زیاد رخ ندهد و زمان اجرای میانگین، مطلوب باشد. اگر مجموعۀ الفبا باشد، به طور معمول اینگونه تعریف می‌شود: و نیز عموماً یک عدد اول بزرگ در نظر گرفته می‌شود به طوری که در یک کلمه از کامپیوترcomputer word جا بگیرد. | ## بخش 3: الگوریتم جستجوی رشته رابین-کارپ | برای مثال اگر فرض کنیم ، متن موردنظر ما و برای راحتی کار باشد، خواهیم داشت: و مقدار درهم‌سازی زیررشته "31415" به طول 5 از متن برابر است با: ( 3×104 + 1×103 + 4×102 + 1×101 + 5×100 ) mod 1 = 31415 mod 1 = 31415 مقدار تابع درهم‌سازی تعریف شده را برای هر رشته به طول m می‌توان با استفاده از روش هورنر در زمان به این صورت محاسبه کرد: hash(T[1 .. mod q حال اگر بخواهیم برای هر زیررشته یک‌بار مقدار این تابع را حساب کنیم از آنجا که n-m+1 زیررشته داریم، این کار طول می‌کشد که همان زمان اجرای الگوریتم ساده‌لوحانه می‌باشد و در حقیقت زمان اجرا بهبود نیافته است. درهم‌سازی چرخشی به ما امکان می‌دهد تا مقدار درهم‌سازی زیررشتۀ هر مرحله را از روی مقدار درهم‌سازی زیررشتۀ مرحله قبلی در زمان ثابت به دست بیاوریم. این روند در حال کلی به صورت زیر است: s[i+1..i+m] = s[i..i+m-1] - s[i] + s[i+m] در الگوریتم رابین-کارپ اگر مقدار درهم‌سازی زیررشته در مرحله s ام را بنامیم، رابطۀ درهم‌سازی چرخشی به این صورت خواهد بود: ts+1 = ( d( ts - dm-1 T[s+1] ) + T[s+m+1] ) mod q در مثال گفته شده در بالا اگر بخواهیم مقدار درهم‌سازی زیررشته مرحله بعد یعنی "14156" را از روی مقدار درهم‌سازی زیررشته قبل یعنی "31415" حساب کنیم روند کار به این صورت خواهد بود: ts+1 = ( 10×(31415 - 104 × 3) + 6 ) mod 1 = 14156 در نهایت می‌توان گفت در الگوریتم رابین-کارپ کافی است تنها مقدار درهم‌سازی رشتۀ الگو [P[1..m و مقدار درهم‌سازی زیررشته [T[1..m از متن را در بخش پیش پردازش با زمان محاسبه کرد و سپس محاسبه مقادیر درهم‌سازی زیررشته‌های مراحل بعد در هر مرحله با زمان قابل انجام است. خط 13 نیز در زمان اجرا می‌شود و از آنجا که احتمال اجرای آن در هر بار تکرار حلقه وجود دارد، مرتبۀ زمانی اجرای حلقه در بدترین حالت برابر است. اما در بسیاری از حالت‌ها انتظار می‌رود تطابق رشتۀ الگو و زیررشته، دفعات کمی رخ دهد (مثلاً به تعداد ثابتی مانند c از کل دفعات تکرار حلقه). اگر بخواهیم هر یک از الگوهای با طول ثابت را در متن جستجو کنیم، کافی است گونه‌ای از الگوریتم رابین-کارپ را بسازیم که با استفاده از داده ساختار مجموعه set data structure تعیین می‌کند که آیا مقدار درهم‌سازی زیررشتۀ موردنظر از متن در مجموعۀ مقادیر درهم‌سازی الگوها وجود دارد یا خیر. | ## جمع‌بندی | اما الگوریتم بالا می‌تواند همه الگو را در زمان بیابد زیرا با به‌کارگیری یک جدول درهم‌سازی در زمان می‌توان مشخص کرد که آیا مقدار درهم‌سازی یک زیررشته با مقادیر درهم‌سازی هر یک از الگوها برابر است یا خیر.