[英]C# Boyer-Moore Algorithm with needle can contain a null value as a wildcard
我试图在 C# 中实现 Boyer-Moore 算法,能够使用 null 作为针(模式)中的通配符。
class BoyerMoore
{
private readonly int[] _badChar;
private readonly byte?[] _needle;
public BoyerMoore(byte?[] needle)
{
_needle = needle;
_badChar = new int[256];
// Pre-processing for bad character heuristic
for (int i = 0; i < _badChar.Length; i++)
{
_badChar[i] = -1;
}
for (int i = 0; i < needle.Length; i++)
{
if (needle[i] != null)
_badChar[needle[i].Value] = i;
}
}
public List<int> Search(byte[] haystack)
{
List<int> occurrences = new List<int>();
int i = 0;
while (i <= haystack.Length - _needle.Length)
{
int j;
for (j = _needle.Length - 1; j >= 0; j--)
{
if (_needle[j] == null) continue;
if (_needle[j] != haystack[i + j]) break;
}
if (j < 0)
{
occurrences.Add(i);
i++;
}
else
{
i += Math.Max(1, j - _badChar[haystack[i + j]]);
}
}
return occurrences;
}
}
当针不包含 null 时,我的代码可以正常工作,但当针包含 null(例如0xAA, 0xBB, null, 0xCC
时,它无法正常工作。 (缺少一些结果。)
我是否忽略了某些东西,或者是否无法使用 null 通配符实施 Boyer-Moore Bad Character 启发式算法?
我在谷歌上搜索过,但我没有看到任何示例、教程或解释使用 null 值作为通配符的内容,所以我问了。
Boyer-Moore 不良字符规则不适用于通配符。 基本上,在操作该规则时,您必须丢弃最右边通配符左侧的所有内容。
考虑_badChar
数组为您提供偏移量以快速移动搜索 position,其中您在当前干草堆 position 中看到的字符不在针中。 如果你的 needle 中有一个通配符,那么它可以匹配任何字符,现在你通过将它们的 position 设置为 -1 来表示这些字符与 needle 中的任何内容都不匹配。
因此,与其将针中未明确存在的每个值的_badChar
中的条目设置为 -1,不如将条目设置为针中的最后一个通配符 position。
但是您还必须将针中的每个其他字符设置为position,使其不比该点更靠左,因为它也可以匹配它们。
您可以在设置中执行此操作:
for (int i = 0 ; i < needle.Length; i++)
if (needle[i] != null)
_badChar[needle[i].Value] = i;
else
_lastNull = i;
for (int i = 0; i < _badChar.Length; i++)
if (_badChar[i] < _lastNull)
_badChar[i] = _lastNull;
但是现在您实际上只在针的最右边部分运行 Boyer-Moore,并且每次 Boyer-Moore 算法为您提供匹配时,都会对针的 rest 进行线性匹配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.