สมมติว่าเรามีสตริง S; เราต้องหาจำนวนของสตริงย่อยที่ไม่ว่างที่ชัดเจนของ S ที่สามารถเขียนเป็นการต่อกันของสตริงบางตัวกับตัวมันเองได้
ดังนั้น หากอินพุตเป็นเหมือน "elloelloello" ผลลัพธ์จะเป็น 5 เนื่องจากมีสตริงย่อยบางตัว เช่น "ello", "lloe", "loel", "oell"
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
เฉพาะ :=31
-
ม :=1^9 + 7
-
กำหนดฟังก์ชัน fastPow() ซึ่งจะยึดฐาน พลัง
-
res :=1
-
ในขณะที่กำลัง> 0 ทำ -
-
ถ้ากำลัง &1 ไม่ใช่ศูนย์ ดังนั้น −
-
res :=res * ฐาน
-
res :=res mod m
-
-
ฐาน :=ฐาน * ฐาน
-
ฐาน :=ตัวดัดแปลงฐาน m
-
พลัง =พลัง / 2
-
-
ผลตอบแทน
-
กำหนดฟังก์ชัน createHashValue() ซึ่งจะใช้เวลา s, n,
-
ผลลัพธ์ :=0
-
สำหรับการเริ่มต้น i :=0 เมื่อ i
-
ผลลัพธ์ :=ผลลัพธ์ + (s[i] * fastPow(prime, i))
-
ผลลัพธ์ :=ผลลัพธ์ mod m
-
-
ส่งคืนผลลัพธ์
-
กำหนดฟังก์ชัน recalculateHash() ซึ่งจะใช้ old, newC, oldHash, patLength
-
newHash :=oldHash - เก่า
-
newHash :=newHash * fastPow(prime, m - 2)
-
newHash :=newHash + (newC * fastPow(prime, patLength - 1))
-
newHash :=newHash mod m
-
คืนค่าแฮชใหม่
-
จากวิธีหลัก ให้ทำดังต่อไปนี้ −
-
n :=ขนาดของข้อความ
-
กำหนดหนึ่งชุดและ
-
สำหรับการเริ่มต้น i :=2 เมื่อฉัน <=n อัปเดต i :=i + 2 ทำ −
-
temp :=สตริงว่าง
-
สำหรับการเริ่มต้น j :=0 เมื่อ j
-
temp :=temp + text[j]
-
-
hash1 :=createHashValue(ชั่วคราว, i / 2)
-
temp :=สตริงว่าง)
-
สำหรับการเริ่มต้น j :=i / 2 เมื่อ j
-
temp :=temp + text[j]
-
-
hash2 :=createHashValue(ชั่วคราว, i / 2)
-
สำหรับการเริ่มต้น s1 :=0, e1 :=i / 2, s2 :=i / 2, e2 :=i เมื่อ e2
-
ถ้า hash1 เหมือนกับ hash2 แล้ว
-
ใส่ hash1 ลงใน ans
-
-
hash1 :=recalculateHash(text[s1], text[e1], hash1, i / 2)
-
hash2 :=recalculateHash(text[s2], text[e2], hash2, i / 2)
-
-
ถ้า hash1 เหมือนกับ hash2 แล้ว
-
ใส่ hash1 ลงใน ans
-
-
-
ขนาดส่งคืนของ ans
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
const lli prime = 31;
const lli m = 1e9 + 7;
class Solution {
public:
lli fastPow(lli base, lli power){
lli res = 1;
while (power > 0) {
if (power & 1) {
res = res * base;
res %= m;
}
base *= base;
base %= m;
power >>= 1;
}
return res;
}
lli createHashValue(string s, lli n){
lli result = 0;
for (lli i = 0; i < n; i++) {
result += (lli)(s[i] * fastPow(prime, i));
result %= m;
}
return result;
}
lli recalculateHash(char old, char newC, lli oldHash, lli
patLength){
lli newHash;
newHash = oldHash - (lli)old;
newHash *= fastPow(prime, m - 2);
newHash += ((lli)newC * fastPow(prime, patLength - 1));
newHash %= m;
return newHash;
}
int distinctEchoSubstrings(string text){
int n = text.size();
set<int> ans;
for (int i = 2; i <= n; i += 2) {
string temp = "";
for (int j = 0; j < i / 2; j++) {
temp += text[j];
}
int hash1 = createHashValue(temp, i / 2);
temp = "";
for (int j = i / 2; j < i; j++) {
temp += text[j];
}
int hash2 = createHashValue(temp, i / 2);
for (int s1 = 0, e1 = i / 2, s2 = i / 2, e2 = i; e2 < n;
s1++, s2++, e1++, e2++) {
if (hash1 == hash2) {
ans.insert(hash1);
}
hash1 = recalculateHash(text[s1], text[e1], hash1,
i / 2);
hash2 = recalculateHash(text[s2], text[e2], hash2,
i / 2);
}
if (hash1 == hash2) {
ans.insert(hash1);
}
}
return ans.size();
}
};
main(){
Solution ob;
cout << (ob.distinctEchoSubstrings("elloelloello"));
} อินพุต
"elloelloello"
ผลลัพธ์
5