gpt4 book ai didi

javascript - 为什么这个使用散列搜索字符串的函数不起作用?

转载 作者:行者123 更新时间:2023-11-29 22:49:01 29 4
gpt4 key购买 nike

我写了一个函数,给定 2 个字符串,s 和 a,它应该返回 s 中 a 第一次出现的位置。它作为一个字符可以很好地工作,但如果第一次出现在 s 中的第三个字符之后,它就会停止工作。

我已经检查了 mul 和 add 是否有效,a 的散列是否正确并且我已经将基数减少到 10 和 100(这对散列不是很好,因为它们不是质数)并且它有效(在长度为 20 的字符串)。这可能意味着模不能按预期工作。

function getIndex(s, a) {

// 2 bases and 2 mods to reduce the number of collisions

var base1 = 31337;
var base2 = 31357;

var mod1 = 1e9 + 7;
var mod2 = 1e9 + 9;

//suffix arrays

var hs1 = new Uint32Array(s.length);
var hs2 = new Uint32Array(s.length);

// bases to the power of a.length

var ba1 = 1;
var ba2 = 1;

// hashes for a

var ha1 = 0;
var ha2 = 0;

//operators

var mul = (x, y, mod) => (x * y) % mod;

var add = (x, y, mod) => {
x += y;
if(x >= mod) x -= mod;
if(x < 0) x += mod;
return x;
}

//get hash of a and find value of ba1 and ba2

for(var i = 0; i < a.length; i++) {
ha1 = add(mul(ha1, base1, mod1), a.charCodeAt(i), mod1);
ha2 = add(mul(ha2, base2, mod2), a.charCodeAt(i), mod2);

ba1 = mul(ba1, base1, mod1);
ba2 = mul(ba2, base2, mod2);
}

//make suffix array

var h1 = 0;
var h2 = 0;

for(var i = 0; i < s.length; i++) {
h1 = add(mul(h1, base1, mod1), s.charCodeAt(i), mod1);
h2 = add(mul(h2, base2, mod2), s.charCodeAt(i), mod2);

hs1[i] = h1;
hs2[i] = h2;
}

//Compare hashes of substrings of s (by removing prefix from the current element) with hash of a

for(var i = a.length - 1; i < s.length; i++) {
var h1 = hs1[i];
var h2 = hs2[i];
if(i >= a.length) {
console.log(i, i - a.length, h1);
h1 = add(h1, -mul(hs1[i - a.length], ba1, mod1), mod1);
h2 = add(h2, -mul(hs2[i - a.length], ba2, mod2), mod2);
}
if(h1 == ha1 && h2 == ha2) return i - a.length + 1;
}

return -1;
}
getIndex("abcdefgh", "f") //returns 5
getIndex("abcdefgh", "fg")//returns -1

最佳答案

通过更多的日志记录,很明显您是 floating point inaccuracies 的受害者. JS数字只能精确表示52位整数。

getIndex("abcdefgh", "fg")中,搜索到的哈希值ha13196477,你的基础乘数ba1 982007569,在第六次迭代中,前缀哈希是 hs1[6] = 73644174hs1[4] = 800389532 .如果将它们放入算术函数中,结果为 3196441,相差 6。这是因为 800389532 * 982007569maximum safe integer 大两个数量级。在 JS 中计算结果为 785988578572367700,这显然是错误的。

您需要选择更小的模数和基数,或者使用 biints 进行所有计算。

关于javascript - 为什么这个使用散列搜索字符串的函数不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57768934/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com