I tried this problem below and solved it in O(test_cases * string_length * pattern_length) complexity involving three nested loops. I want to know how can I further decrease time. I figured as much:
1: I'm comparing few patterns more than once.
2: Should find a way to not repeat the comparisons which I am unable to do.
The problem is as below:-
We are given a string S and a Pattern P. You need to find all matches of hash of P in string S. Also, print the index (0 based) at which the pattern's hash is found. If no match is found, print -1.
Note: All the matches should have same length as pattern P.
The hash of pattern P is calculated by summing the values of characters as they appear in the alphabets table. For reference, a is 1, b is 2, ...z is 26. Now, using the mentioned values, hash of ab is 1+2=3.
Input:
The first line of input contains T denoting the number of testcases. T testcases follow. Each testcase contains two lines of input. The first line contains the string S. The second line contains the pattern P.
Output:
For each testcase, in a new line, print the matches and index separated by a space. All the matches should be printed in their own separate lines.
Constraints:
1 <= T <= 100
1 <= |S|, |P| <= 10⁵Examples:
Input:
1
bacdaabaa
aab
Output:
aab 4
aba 5
baa 6 Explanation:Testcase1:
P is aab, and S is bacdaabaa
Now, the hash of P: aab is 1+1+2=4
In the string S, the hash value of 4 is obtained by the following:aab=1+1+2=4, at index 4
aba=1+2+1=4, at index 5
baa=2+1+1=4, at index 6
My code in C++ :-
#include <iostream> #include <string> #include <vector> using namespace std; int main() { long ind,j,test,kal; cin>>test; //testcases' input// for(ind=0;ind<test;ind++) { long len1,len2,sum1=0,sum2=0; string s1,s2,s3; //s1 for the input string,s2 for pattern,s3 to print the patterns that we find// cin>>s1>>s2; len1=s1.size(); //length of input string// len2=s2.size(); //length of pattern // for(j=0;j<len2;j++) { sum2=sum2+(int)s2[j]-96; //doing the hash sum of pattern first so that i need not do pattern matching// } for(j=0;j<=len1-len2;j++) //iterate len1-len2 times since we get those many distinct or duplicate patterns// { for(kal=j;kal<j+len2;kal++) //iterate j+len2 times which is size of the pattern each time// { sum1=sum1+(int)s1[kal]-96; //updating the sum obtained// s3.push_back(s1[kal]); //since we also need to print the pattern which has the hash sum// } if(sum1==sum2) //if the sum matches print the string and starting index// cout<<s3<<" "<<j<<endl; s3.erase(); //clear the string for next testcase// sum1=0; //clear the sum for next testcase// } } return 0;} Please suggest changes that reduces the time.