
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
- Selected Reading
- UPSC IAS Exams Notes
- Developer's Best Practices
- Questions and Answers
- Effective Resume Writing
- HR Interview Questions
- Computer Glossary
- Who is Who
Distinct Echo Substrings in C++
Suppose we have a string S; we have to find the number of distinct non-empty substrings of S that can be written as the concatenation of some string with itself.
So, if the input is like "elloelloello", then the output will be 5, as there are some substrings like "ello", "lloe", "loel", "oell".
To solve this, we will follow these steps −
prime := 31
m := 1^9 + 7
Define a function fastPow(), this will take base, power,
res := 1
-
while power > 0, do −
-
if power & 1 is non-zero, then −
res := res * base
res := res mod m
base := base * base
base := base mod m
power = power / 2
-
return res
Define a function createHashValue(), this will take s, n,
result := 0
-
for initialize i := 0, when i < n, update (increase i by 1), do −
result := result + (s[i] * fastPow(prime, i))
result := result mod m
return result
Define a function recalculateHash(), this will take old, newC, oldHash, patLength,
newHash := oldHash - old
newHash := newHash * fastPow(prime, m - 2)
newHash := newHash + (newC * fastPow(prime, patLength - 1))
newHash := newHash mod m
return newHash
From the main method do the following −
n := size of text
Define one set ans
-
for initialize i := 2, when i <= n, update i := i + 2, do −
temp := empty string
-
for initialize j := 0, when j < i / 2, update (increase j by 1), do −
temp := temp + text[j]
hash1 := createHashValue(temp, i / 2)
temp := empty string)
-
for initialize j := i / 2, when j < i, update (increase j by 1), do −
temp := temp + text[j]
hash2 := createHashValue(temp, i / 2)
-
for initialize s1 := 0, e1 := i / 2, s2 := i / 2, e2 := i, when e2 < n, update (increase s1, s2, e1, e2 by 1), do −
-
if hash1 is same as hash2, then
insert hash1 into ans
hash1 := recalculateHash(text[s1], text[e1], hash1, i / 2)
hash2 := recalculateHash(text[s2], text[e2], hash2, i / 2)
-
-
if hash1 is same as hash2, then
insert hash1 into ans
return size of ans
Let us see the following implementation to get better understanding −
Example
#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")); }
Input
"elloelloello"
Output
5