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.