- Trending Categories
Data Structure
Networking
RDBMS
Operating System
Java
MS Excel
iOS
HTML
CSS
Android
Python
C Programming
C++
C#
MongoDB
MySQL
Javascript
PHP
Physics
Chemistry
Biology
Mathematics
English
Economics
Psychology
Social Studies
Fashion Studies
Legal Studies
- 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