Module: تابع پیشوند، تابع Z


Problem

1/10

(C++) جستجوی زیر رشته، KMP، نوع بی اهمیت: شروع

Theory Click to read/hide

برای حل این مشکل، شمارش معمول کار نخواهد کرد، زیرا مجانبی آن O(t*s) خواهد بود. بنابراین، برای کارهای جستجوی زیر رشته ای، از الگوریتم KMP (Knuth-Morris-Pratt) استفاده می شود.
برای پیاده سازی این الگوریتم، از تابع پیشوند رشته استفاده می شود، این آرایه ای از اعداد طول (strong>s طول) است که در آن هر عنصر  حداکثر طول است. از بزرگترین پسوند خود رشته فرعی s، با پیشوند آن مطابقت دارد. به عنوان مثال:
 

<بدن>
خط عملکرد پیشوند یادداشت
abababcab 0 0 1 2 3 4 0 1 2  
abcabcd 0 0 0 1 2 3 0  
aabaaab 0 1 0 1 2 2 3  

الگوریتم تابع پیشوند بی اهمیت با مجانبی O(n^3):

ایجاد شد
بردار<int> prefix_function (رشته ها) {
int n = (int ) s.length();
بردار<int>pi(n);
برای (int i=0; i<n; ++i)
برای (int k=0; k<=i; ++k)
اگر (s.substr(0,k) == s .substr(i-k+1،k))
pi[i] = k;
بازگشتpi;
}

و اکنون باید یک تابع پیشوند برای رشته ای از فرم بسازیم: & nbsp; t + # + s، که در آن # یک کاراکتر جداکننده است که به وضوح در متن نیست.  با تجزیه و تحلیل مقادیر تابع پیشوند پس از کاراکتر جداکننده مربوطه، باید توجه داشت که اگر مقدار حاصل برابر با طول زیر رشته مورد نظر باشد، وقوع آن پیدا می شود. به عنوان مثال، برای رشته "abababcab» و زیر رشته مورد نظر "abab"، تابع پیشوند به صورت:
خواهد بود 0 0 1 2 0 1 2 3 4 3 4 0 1 2 ما باید عناصر رشته مربوطه s را تجزیه کنیم:
1 2 3 4 3 4 0 1 2 - دو مورد وجود دارد که مقدار آن 4 است (4 و 6)، یعنی. طول t،  در نتیجه، پاسخ باید نوشته شود: 4 - 4 (طول t) & nbsp; = 0 و 6 - 4 = 2. مشاهده می شود که اینها پاسخ های صحیح و رشته "abab" در واقع یک زیر رشته در رشته "abababcab" در موقعیت های 0 و 2.

 

Problem

همه تکرارهای رشته t را در رشته s پیدا کنید.
 
ورودی
در خط اول  رشته s نوشته شده است، خط دوم شامل رشته t است. هر دو رشته فقط از حروف انگلیسی تشکیل شده است. طول خط می تواند از 1 تا 50000 شامل باشد.
 
خروجی
در پاسخ، تمام رخدادهای رشته t در رشته s را به ترتیب صعودی خروجی بگیرید. شماره گذاری موقعیت های خط از صفر شروع می شود.
 

 

نمونه‌ها
<سر> <بدن>
# ورودی خروجی
1
abababcab
اباب
0 2