我需要一些关于我的 Karp-Rabin 算法的特定部分的帮助。我想要做的是用固定sliding window
和单独append
的skip
部分来实现版本。Sliding window
工作得很好。当我尝试将整体拆分为sliding window
多个append
部分时,就会出现问题skip
。Append
似乎工作正常,但这skip
是过去几天让我头疼的事情。
问题- 我正在滑过包含几个订阅模式实例的字符串。Sliding window
检测到它,但没有检测到其他两个。
这个想法是该结构保存(base ^ window size)mod prime number( )RH
的预先计算值,因此我可以删除字符串的前导字符。这个值毕竟会随着窗口大小的变化而变化。为了减小 的值,乘法逆用于不处于模删除的情况(基模模值的逆)。它也是预先计算的。b2wmod
append
skip
b2wmod
以下是我感兴趣的代码部分。我不发布整个代码以免您阅读所有内容,但如果需要可以上传。乘法逆似乎计算正确,但我也可以上传代码。
将不胜感激任何帮助!先感谢您!
void
append_to_rh(RH rh)
{
uint64_t hash = rh->hash;
uint64_t base = rh->base;
uint64_t mod = rh->mod;
uint64_t b2wmodm = rh->b2wmodm;
char new = rh->new;
hash = ( hash * base + new ) % mod;
b2wmodm = ( b2wmodm * base ) % mod;
rh->hash = hash;
rh->b2wmodm = b2wmodm;
}
void
skip(RH rh)
{
uint64_t hash = rh->hash;
uint64_t base = rh->base;
uint64_t mod = rh->mod;
uint64_t b2wmodm = rh->b2wmodm;
uint64_t m_inv = rh->m_inv;
char old = rh->old;
uint64_t correction = old * mod;
b2wmodm = ( b2wmodm * (m_inv % mod) ) % mod;
hash = ( hash - old * b2wmodm + correction ) % mod;
rh->hash = hash;
rh->b2wmodm = b2wmodm;
}
void
slide_window(RH rh)
{
uint64_t base = rh->base;
uint64_t mod = rh->mod;
uint64_t hash = rh->hash;
uint64_t b2wmodm = rh->b2wmodm;
char old = rh->old;
char new = rh->new;
hash = ( hash * base - old * b2wmodm + new ) % mod;
rh->hash = hash;
}