Palindrome Substring Queries - GeeksforGeeks
Given a string and several queries on the substrings of the given input string to check whether the substring is a palindrome or not.
The idea is similar to Rabin Karp string matching. We use string hashing. What we do is that we calculate cumulative hash values of the string in the original string as well as the reversed string in two arrays- prefix[] and suffix[].
Read full article from Palindrome Substring Queries - GeeksforGeeks
Given a string and several queries on the substrings of the given input string to check whether the substring is a palindrome or not.
The idea is similar to Rabin Karp string matching. We use string hashing. What we do is that we calculate cumulative hash values of the string in the original string as well as the reversed string in two arrays- prefix[] and suffix[].
How to calculate the cumulative hash values ?
Suppose our string is str[], then the cumulative hash function to fill our prefix[] array used is-
prefix[0] = 0
prefix[i] = str[0] + str[1] * 101 + str[2] * 1012 +
...... + str[i-1] * 101i-1
For example, take the string- “abaaabxyaba”
prefix[0] = 0
prefix[1] = 97 (ASCII Value of ‘a’ is 97)
prefix[2] = 97 + 98 * 101
prefix[3] = 97 + 98 * 101 + 97 * 1012
...........................
...........................
prefix[11] = 97 + 98 * 101 + 97 * 1012 +
........+ 97 * 10110
Now the reason to store in that way is that we can easily find the hash value of any substring in O(1) time using-
hash(L, R) = prefix[R+1] – prefix[L]
For example, hash (1, 5) = hash (“baaab”) = prefix[6] – prefix[1] = 98 * 101 + 97 * 1012 + 97 * 1013 + 97 * 1014 + 98 * 1015 = 1040184646587 [We will use this weird value later to explain what’s happening].
// Structure to represent a query. A query consists// of (L,R) and we have to answer whether the substring// from index-L to R is a palindrome or notstruct Query{ int L, R;};// A function to check if a string str is palindrome// in the ranfe L to Rbool isPalindrome(string str, int L, int R){ // Keep comparing characters while they are same while (R > L) if (str[L++] != str[R--]) return(false); return(true);}// A Function to find pow (base, exponent) % MOD// in log (exponent) timeunsigned long long int modPow(unsigned long long int base, unsigned long long int exponent){ if (exponent == 0) return 1; if (exponent == 1) return base; unsigned long long int temp = modPow(base, exponent/2); if (exponent %2 ==0) return (temp%MOD * temp%MOD) % MOD; else return ((( temp%MOD * temp%MOD)%MOD) * base%MOD) % MOD;}// A Function to calculate Modulo Multiplicative Inverse of 'n'unsigned long long int findMMI(unsigned long long int n){ return modPow(n, MOD-2);}// A Function to calculate the prefix hashvoid computePrefixHash(string str, int n, unsigned long long int prefix[], unsigned long long int power[]){ prefix[0] = 0; prefix[1] = str[0]; for (int i=2; i<=n; i++) prefix[i] = (prefix[i-1]%MOD + (str[i-1]%MOD * power[i-1]%MOD)%MOD)%MOD; return;}// A Function to calculate the suffix hash// Suffix hash is nothing but the prefix hash of// the reversed stringvoid computeSuffixHash(string str, int n, unsigned long long int suffix[], unsigned long long int power[]){ suffix[0] = 0; suffix[1] = str[n-1]; for (int i=n-2, j=2; i>=0 && j<=n; i--,j++) suffix[j] = (suffix[j-1]%MOD + (str[i]%MOD * power[j-1]%MOD)%MOD)%MOD; return;}// A Function to answer the Queriesvoid queryResults(string str, Query q[], int m, int n, unsigned long long int prefix[], unsigned long long int suffix[], unsigned long long int power[]){ for (int i=0; i<=m-1; i++) { int L = q[i].L; int R = q[i].R; // Hash Value of Substring [L,R] unsigned long long hash_LR = ((prefix[R+1]-prefix[L]+MOD)%MOD * findMMI(power[L])%MOD)%MOD; // Reverse Hash Value of Substring [L,R] unsigned long long reverse_hash_LR = ((suffix[n-L]-suffix[n-R-1]+MOD)%MOD * findMMI(power[n-R-1])%MOD)%MOD; // If both are equal then the substring is a palindrome if (hash_LR == reverse_hash_LR ) { if (isPalindrome(str, L, R) == true) printf("The Substring [%d %d] is a " "palindrome\n", L, R); else printf("The Substring [%d %d] is not a " "palindrome\n", L, R); } else printf("The Substring [%d %d] is not a " "palindrome\n", L, R); } return;}// A Dynamic Programming Based Approach to compute the// powers of 101void computePowers(unsigned long long int power[], int n){ // 101^0 = 1 power[0] = 1; for(int i=1; i<=n; i++) power[i] = (power[i-1]%MOD * p%MOD)%MOD; return;}Read full article from Palindrome Substring Queries - GeeksforGeeks