آرایه ال‌سی‌پی

از testwiki
نسخهٔ تاریخ ۲۸ فوریهٔ ۲۰۲۳، ساعت ۰۶:۱۶ توسط imported>Rezarafeezadeh (growthexperiments-addlink-summary-summary:3|0|0)
(تفاوت) → نسخهٔ قدیمی‌تر | نمایش نسخهٔ فعلی (تفاوت) | نسخهٔ جدیدتر ← (تفاوت)
پرش به ناوبری پرش به جستجو
آرایه ال‌سی‌پی
نوع آرایه
اختراع شده توسط الگو:Harvard citation text
زمان اجرای الگوریتمالگو:سخ

در نماد O بزرگ

متوسط بدترین حالت
حافظه 𝒪(n) 𝒪(n)
ساخت 𝒪(n) 𝒪(n)

در علوم رایانه، آرایه بلندترین پیشوند مشترک (آرایه ال‌سی‌پی) الگو:انگلیسی یک داده‌ساختار کمکی برای آرایه پسوندی است. در این آرایه، طولانی‌ترین پیشوند مشترک بین هر دو پسوند متوالی موجود در آرایه پسوندی ذخیره می‌شود.

تاریخچه

آرایه ال‌سی‌پی توسط Udi Manber و Gene Myers در سال ۱۹۹۰ به همراه آرایه پسوندی و برای بهبود سرعت الگوریتم جستجوی الگو در متن ارائه شد.[۱]

تعریف

فرض کنیم A آرایه پسوندی رشته S=S[1]S[2]...S[n] بوده و lcp(v,w) نشان‌دهندهٔ طولانی‌ترین پیشوند مشترک رشته‌های v و w باشد. هم چنین زیررشتهٔ S از حرف i ام تا حرف j ام را با S[i,j] نشان می‌دهیم. در این صورت آرایه ال‌سی‌پی H[1,n] یک آرایه با اندازهٔ n از اعداد صحیح است که H[1] تعریف نشده‌است و H[i]=lcp(S[A[i1],n],S[A[i],n]) به ازای هر 1<in. با توجه به اینکه A[i] نشان‌دهندهٔ جایگاه شروع i امین کوچک‌ترین پسوند رشتهٔ S از نظر لغتنامه‌ای است، پس H[i] طول بلندترین پیشوند مشترک i1 امین و i امین پسوند رشتهٔ S از نظر لغتنامه‌ای است (1<in).

مثال

رشتهٔ S=banana$ را در نظر بگیرید:

الگو:Left header | i ۱ ۲ ۳ ۴ ۵ ۶ ۷
الگو:Left header | S[i] b a n a n a $

و آرایهٔ پسوندی مرتب‌شدهٔ متناظر با آن:

الگو:Left header | i ۱ ۲ ۳ ۴ ۵ ۶ ۷
الگو:Left header | A[i] ۷ ۶ ۴ ۲ ۱ ۵ ۳

پسوندهای رشتهٔ S که به صورت ستونی و مرتب‌شده نوشته شده‌اند:

الگو:Left header | i ۱ ۲ ۳ ۴ ۵ ۶ ۷
الگو:Left header | A[i] ۷ ۶ ۴ ۲ ۱ ۵ ۳
الگو:Left header | 1 $ a a a b n n
الگو:Left header | 2 $ n n a a a
الگو:Left header | 3 a a n $ n
الگو:Left header | 4 $ n a a
الگو:Left header | 5 a n $
الگو:Left header | 6 $ a
الگو:Left header | 7 $

آرایهٔ ال‌سی‌پی با مقایسهٔ پسوندهای متوالی از نظر لغت‌نامه‌ای برای مشخص کردن بزرگ‌ترین پیشوند مشترک آن‌ها محاسبه می‌شود:

الگو:Left header | i ۱ ۲ ۳ ۴ ۵ ۶ ۷
الگو:Left header | H[i] ۰ ۱ ۳ ۰ ۰ ۲

برای مثال، H[4]=3 طول بزرگ‌ترین پیشوند مشترک بین S[A[3],7]=S[4,7]=ana$ و S[A[4],7]=S[2,7]=anana$ یعنی رشته ana است.

استفاده از آرایه ال‌سی‌پی برای جستجوی یک الگو در متن

فرض کنید می‌خواهیم تعداد رخدادهای یک الگوی P (به طول m) در یک متن T (به طول N) را بیابیم. می‌توان با دو بار استفاده از جستجوی دودویی، مکان اولین و آخرین رخداد P در آرایه پسوندی T را بدست آورد و در نتیجه تعداد رخدادهای رشته P در متن T بدست می‌آید. در هر کدام از جستجوهای دودویی O(logN) مقایسه نیاز است و با توجه به اینکه در هر مقایسه رشتهٔ P را با یکی از عناصر آرایه پسوندی مقایسه می‌کنیم، در بدترین حالت ممکن است نیاز به مقایسهٔ کامل دو رشته باشد که به معنی مقایسهٔ m کاراکتر است؛ بنابراین زمان اجرای این الگوریتم از O(m×logN) است.

با استفاده از آرایه ال‌سی‌پی، الگوریتمی با زمان اجرای O(m+logN) ارائه می‌دهیم.[۱] به ازای هر 1in، Si را برابر S[A[i],n] تعریف می‌کنیم؛ در واقع Si برابر iامین کوچک‌ترین پسوند S است. ابتدا فرض کنیم به ازای هر 1i,jn مقدار lcp(Si,Sj) از قبل محاسبه شده‌است. در هر مرحله از جستجوی دودویی، یک بازه (L,...,R)در آرایه پسوندی به همراه نقطه میانی آن M را در نظر می‌گیریم. سپس با مقایسهٔ P وSM مشخص می‌کنیم که جستجو را در بازهٔ (L,...,M) ادامه دهیم یا بازهٔ (M,...,R). فرض کنیم P بزرگتر از SM باشد و اولین حرفی از P و SM که متفاوت اند حرف k+1 ام باشد؛ یعنی lcp(P,SM)=k. پس در مرحلهٔ بعدی جستجو، بازه (M,...,R) با نقطه میانی M را در نظر می‌گیریم. با توجه به فرضی که کردیم، مقدار lcp(SM,SM)=k از قبل محاسبه شده‌است و در زمان O(1) قابل دسترس است. سه حالت ممکن است پیش بیاید:

  • حالت ۱: k<k، یعنی طولانی‌ترین پیشوند مشترک P و SM کمتر از طولانی‌ترین پیشوند مشترک SM و SM است؛ بنابراین k+1 امین حرف SM و SM یکسان است و چون P>SM در نتیجه P>SM. بنابراین جستجو را در بازهٔ (M,...,R) ادامه می‌دهیم.
  • حالت ۲: k>k، یعنی P و SM پیشوند مشترک بیشتری نسبت به SM و SM دارند. با توجه به اینکه آرایه پسوندی با ترتیب لغت‌نامه‌ای مرتب شده‌است، پس SM>SM. از آنجا که اولین حرفی که SM و SM در آن متفاوت اند حرف k+1 ام است و رشته‌های P و SM در این حرف یکسان اند، پس SM>Pو در نتیجه جستجو در بازه (M,...,M) ادامه می‌یابد.
  • حالت ۳: k=k، یعنی رشته‌های SM و SM در k حرف اول با رشتهٔ P یکسان اند. برای مقایسه رشته‌های SM و P، این دو رشته را از حرف k+1 ام به بعد مقایسه می‌کنیم تا به اولین حرف متفاوت برسیم. به این ترتیب در مرحلهٔ بعدی الگوریتم جستجوی دودویی، مقدار lcp(P,SM) را داریم و می‌توانیم به همین صورت الگوریتم جستجوی P را ادامه دهیم.

در الگوریتم بالا هر کاراکتر از رشتهٔ P حداکثر یک بار با کاراکترهای متن T مقایسه می‌شود؛ بنابراین زمان اجرای این الگوریتم O(m+logN) است.

اما فرض کرده بودیم به ازای هر 1i,jn مقدار lcp(Si,Sj) از قبل محاسبه شده‌است. توجه کنیم که همهٔ بازه‌های ممکن (L,...,R) در الگوریتم جستجوی دودویی ظاهر نمی‌شوند. به ازای هر نقطهٔ 2Mn1، دقیقاً یک بازه با نقطهٔ میانی M وجود دارد که در الگوریتم جستجوی دودویی ممکن است ظاهر شود. این بازه را با (LM,M,RM) نشان می‌دهیم و به ازای هر 2Mn1 تعریف می‌کنیم:

  • Llcp[M]=lcp(SLM,SM)
  • Rlcp[M]=lcp(SM,SRM)

با توجه به الگوریتم گفته شده، فقط به مقادیر آرایه‌های Llcp و Rlcp نیاز داریم که حافظه‌ای از O(N) اشغال می‌کنند. هم‌چنین از روی آرایه ال‌سی‌پی و در زمان O(N) می‌توان مقادیر Llcp و Rlcp را محاسبه کرد.

ساختن آرایه ال‌سی‌پی

در سال ۱۹۹۰ Manber و Myers الگوریتمی از O(NlogN) دادند که در کنار آرایه پسوندی، آرایه ال‌سی‌پی را نیز محاسبه می‌کند.[۱] در سال ۲۰۰۳ الگوریتمی از O(N) برای ساختن هم‌زمان آرایه پسوندی و آرایه ال‌سی‌پی ارایه شد.[۲]

در سال ۲۰۰۱ الگوریتمی ارایه شد که در O(N) آرایه ال‌سی‌پی را از روی متن و آرایه پسوندی محاسبه می‌کند.[۳]

جستارهای وابسته

منابع

الگو:پانویس