Алгоритм Рабина-Карпа в C#
Я реализовал алгоритм Рабина-Карпа в C#.NET, следуя этому псевдокоду:
Проблема в том, что шаблон не соответствует исходному тексту. Я тщательно просмотрел код, но не могу определить проблему в своем коде. Может кто-нибудь показать мне ошибку в моем коде?
static void Main(string[] args)
{
string text = "ratcatpat catbats";
string pattern = "cat";
int d = text.Select(e => e).Distinct().Count();
RabinCarp(text, pattern, d, 17);
Console.ReadKey();
}
static void RabinCarp(string text, string pattern, int sizeOfAlphabet, int moduloValue)
{
int rollingHashOf_P = 0;
int rollingHashOf_T = 0;
int lengthOfText = text.Length;
int lengthOfPattern = pattern.Length;
int h = (int)(Math.Pow(sizeOfAlphabet, lengthOfPattern - 1) % moduloValue);
for (int i = 0; i < lengthOfPattern; i++)
{
rollingHashOf_P = (sizeOfAlphabet * rollingHashOf_P + (int)pattern[i]) % moduloValue;
rollingHashOf_T = (sizeOfAlphabet * rollingHashOf_T + (int)text[i]) % moduloValue;
}
int diffNM = lengthOfText - lengthOfPattern;
for (int i = 0; i <= diffNM; i++)
{
if (Math.Abs(rollingHashOf_P) == Math.Abs(rollingHashOf_T))
{
if (text.Substring(i, lengthOfPattern).Contains(pattern))
{
string message = "pattern identified";
Console.WriteLine(message);
}
}
if (i < diffNM)
{
rollingHashOf_T = Math.Abs(sizeOfAlphabet * (rollingHashOf_T - (int)text[i] * h) + (int)text[i + lengthOfPattern]) % moduloValue;
}
}
}
1 ответ
Я не знаком с алгоритмом Рабина-Карпа, но я уверен, что вы должны продвигаться rollingHashOf_P
а также rollingHashOf_T
:
if (i < diffNM)
{
rollingHashOf_T = Math.Abs(sizeOfAlphabet * (rollingHashOf_T - (int)text[i] * h) + (int)text[i + lengthOfPattern]) % moduloValue;
rollingHashOf_P = Math.Abs(sizeOfAlphabet * (rollingHashOf_P - (int)pattern[i] * h) + (int)pattern[i + lengthOfPattern]) % moduloValue;
}
После того, как ОП поделился этим псевдокодом в комментарии ниже:
Понятно, что вышесказанное неверно. Сравнение этого с кодом в посте, хотя показывает, что ошибка может быть в продвижении строки rollingHashOf_T
в конце концов, как говорится:
rollingHashOf_T = Math.Abs(sizeOfAlphabet * (rollingHashOf_T -
(int)text[i] * h) + (int)text[i + lengthOfPattern]) % moduloValue;
Хотя псевдокод предполагает, что это должно быть:
rollingHashOf_T = Math.Abs(sizeOfAlphabet * (rollingHashOf_T -
(int)text[i + 1] * h) + (int)text[i + lengthOfPattern + 1]) % moduloValue;