Блог пользователя badam_milk

Автор badam_milk, история, 4 года назад, По-английски

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.

Полный текст и комментарии »

  • Проголосовать: нравится
  • -13
  • Проголосовать: не нравится

Автор badam_milk, история, 4 года назад, По-английски

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.

Полный текст и комментарии »

  • Проголосовать: нравится
  • +7
  • Проголосовать: не нравится