badam_milk's blog

By badam_milk, history, 4 years ago, In English

I have recently learned about string hashing and about Rabin-Karp algorithm for string matching from here. Here's the code taken directly from cp-algorithms site:

vector<int> rabin_karp(string const& s, string const& t) {
    const int p = 31; 
    const int m = 1e9 + 9;
    int S = s.size(), T = t.size();

    vector<long long> p_pow(max(S, T)); 
    p_pow[0] = 1; 
    for (int i = 1; i < (int)p_pow.size(); i++) 
        p_pow[i] = (p_pow[i-1] * p) % m;

    vector<long long> h(T + 1, 0); 
    for (int i = 0; i < T; i++)
        h[i+1] = (h[i] + (t[i] - 'a' + 1) * p_pow[i]) % m; 
    long long h_s = 0; 
    for (int i = 0; i < S; i++) 
        h_s = (h_s + (s[i] - 'a' + 1) * p_pow[i]) % m; 

    vector<int> occurences;
    for (int i = 0; i + S - 1 < T; i++) { 
        long long cur_h = (h[i+S] + m - h[i]) % m; 
        if (cur_h == h_s * p_pow[i] % m)
            occurences.push_back(i);
    }
    return occurences;
}

But, the above algorithm fails for one particular test-case:

S: lNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUX
T:ZtonpqnFzlpvUKZrBbRlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXxtHmTxoLuMbRYsvSpxhtrlvABBlFYmndFzHypOmJyFxjHEPlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXbDiEAvtPlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXRRNoBCUMQVOlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXRLKlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXAYPDKWtVpShhclNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXOJlUlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXglmlNoYhXmlwOscxnkTWjsyNJNhgvzMFbxFnbiWuBAGjZQlCRQHjTUXuaOibGlVrwghvNTgLfltIbEdBlgjelFjQkBeFrdEV

It outputs indices of occurrence of string s as 361 472, whereas the actual correct output is: 19 118 178 241 296 361 417 472

Can anyone point out the reason why it is failing? I have been stuck at this for hours.

Full text and comments »

  • Vote: I like it
  • -13
  • Vote: I do not like it

By badam_milk, history, 4 years ago, In English

Hello everyone,

I have successfully managed to write a recursive program to print all possible combinations of getting a coin change, let's say value:

void print_possible_change(vector<int> &change, int beginWith, int value, vector<vector<int>> &res, vector<int> &temp){
	if(value == 0){
		res.push_back(temp);
	}

	for(int i = beginWith; i < change.size() && change[i] <= value; ++i){
		temp.push_back(change[i]);
		print_possible_change(change, i, value - change[i], res, temp);
		temp.pop_back();
	}
}

The final result of all combinations is stored in res.

This approach clearly runs in exponential time.

Is there an approach that runs in quadratic time or less?

Thank You.

Full text and comments »

  • Vote: I like it
  • +7
  • Vote: I do not like it