Skip to content

Commit c16727d

Browse files
Merge pull request codemistic#484 from Aman5989/patch-19
Create palindrome-substring-queries.cpp
2 parents 24428a7 + 53aac74 commit c16727d

File tree

1 file changed

+173
-0
lines changed

1 file changed

+173
-0
lines changed
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
/* A C++ program to answer queries to check whether
2+
the substrings are palindrome or not efficiently */
3+
#include <bits/stdc++.h>
4+
using namespace std;
5+
6+
#define p 101
7+
#define MOD 1000000007
8+
9+
// Structure to represent a query. A query consists
10+
// of (L, R) and we have to answer whether the substring
11+
// from index-L to R is a palindrome or not
12+
struct Query {
13+
int L, R;
14+
};
15+
16+
// A function to check if a string str is palindrome
17+
// in the range L to R
18+
bool isPalindrome(string str, int L, int R)
19+
{
20+
// Keep comparing characters while they are same
21+
while (R > L)
22+
if (str[L++] != str[R--])
23+
return (false);
24+
return (true);
25+
}
26+
27+
// A Function to find pow (base, exponent) % MOD
28+
// in log (exponent) time
29+
unsigned long long int modPow(
30+
unsigned long long int base,
31+
unsigned long long int exponent)
32+
{
33+
if (exponent == 0)
34+
return 1;
35+
if (exponent == 1)
36+
return base;
37+
38+
unsigned long long int temp = modPow(base, exponent / 2);
39+
40+
if (exponent % 2 == 0)
41+
return (temp % MOD * temp % MOD) % MOD;
42+
else
43+
return (((temp % MOD * temp % MOD) % MOD)
44+
* base % MOD)
45+
% MOD;
46+
}
47+
48+
// A Function to calculate Modulo Multiplicative Inverse of 'n'
49+
unsigned long long int findMMI(unsigned long long int n)
50+
{
51+
return modPow(n, MOD - 2);
52+
}
53+
54+
// A Function to calculate the prefix hash
55+
void computePrefixHash(
56+
string str, int n,
57+
unsigned long long int prefix[],
58+
unsigned long long int power[])
59+
{
60+
prefix[0] = 0;
61+
prefix[1] = str[0];
62+
63+
for (int i = 2; i <= n; i++)
64+
prefix[i] = (prefix[i - 1] % MOD
65+
+ (str[i - 1] % MOD
66+
* power[i - 1] % MOD)
67+
% MOD)
68+
% MOD;
69+
70+
return;
71+
}
72+
73+
// A Function to calculate the suffix hash
74+
// Suffix hash is nothing but the prefix hash of
75+
// the reversed string
76+
void computeSuffixHash(
77+
string str, int n,
78+
unsigned long long int suffix[],
79+
unsigned long long int power[])
80+
{
81+
suffix[0] = 0;
82+
suffix[1] = str[n - 1];
83+
84+
for (int i = n - 2, j = 2; i >= 0 && j <= n; i--, j++)
85+
suffix[j] = (suffix[j - 1] % MOD
86+
+ (str[i] % MOD
87+
* power[j - 1] % MOD)
88+
% MOD)
89+
% MOD;
90+
return;
91+
}
92+
93+
// A Function to answer the Queries
94+
void queryResults(string str, Query q[], int m, int n,
95+
unsigned long long int prefix[],
96+
unsigned long long int suffix[],
97+
unsigned long long int power[])
98+
{
99+
for (int i = 0; i <= m - 1; i++) {
100+
int L = q[i].L;
101+
int R = q[i].R;
102+
103+
// Hash Value of Substring [L, R]
104+
unsigned long long hash_LR
105+
= ((prefix[R + 1] - prefix[L] + MOD) % MOD
106+
* findMMI(power[L]) % MOD)
107+
% MOD;
108+
109+
// Reverse Hash Value of Substring [L, R]
110+
unsigned long long reverse_hash_LR
111+
= ((suffix[n - L] - suffix[n - R - 1] + MOD) % MOD
112+
* findMMI(power[n - R - 1]) % MOD)
113+
% MOD;
114+
115+
// If both are equal then
116+
// the substring is a palindrome
117+
if (hash_LR == reverse_hash_LR) {
118+
if (isPalindrome(str, L, R) == true)
119+
printf("The Substring [%d %d] is a "
120+
"palindrome\n",
121+
L, R);
122+
else
123+
printf("The Substring [%d %d] is not a "
124+
"palindrome\n",
125+
L, R);
126+
}
127+
128+
else
129+
printf("The Substring [%d %d] is not a "
130+
"palindrome\n",
131+
L, R);
132+
}
133+
134+
return;
135+
}
136+
137+
// A Dynamic Programming Based Approach to compute the
138+
// powers of 101
139+
void computePowers(unsigned long long int power[], int n)
140+
{
141+
// 101^0 = 1
142+
power[0] = 1;
143+
144+
for (int i = 1; i <= n; i++)
145+
power[i] = (power[i - 1] % MOD * p % MOD) % MOD;
146+
147+
return;
148+
}
149+
150+
/* Driver program to test above function */
151+
int main()
152+
{
153+
string str = "abaaabaaaba";
154+
int n = str.length();
155+
156+
// A Table to store the powers of 101
157+
unsigned long long int power[n + 1];
158+
159+
computePowers(power, n);
160+
161+
// Arrays to hold prefix and suffix hash values
162+
unsigned long long int prefix[n + 1], suffix[n + 1];
163+
164+
// Compute Prefix Hash and Suffix Hash Arrays
165+
computePrefixHash(str, n, prefix, power);
166+
computeSuffixHash(str, n, suffix, power);
167+
168+
Query q[] = { { 0, 10 }, { 5, 8 }, { 2, 5 }, { 5, 9 } };
169+
int m = sizeof(q) / sizeof(q[0]);
170+
171+
queryResults(str, q, m, n, prefix, suffix, power);
172+
return (0);
173+
}

0 commit comments

Comments
 (0)