在字符串[]中查找字节[]类似于String IndexOf()?

时间:2013-04-11 02:56:36

标签: c# algorithm search

假设我有一个很大的byte[],我不仅希望看到更小的byte[]是否在更大的数组中,而且还在哪里。例如:

byte[] large = new byte[100];
for (byte i = 0; i < 100; i++) {
    large[i] = i;
}
byte[] small = new byte[] { 23, 24, 25 };

int loc = large.IndexOf(small); // this is what I want to write

我想我要求在更大的序列中寻找任何类型的序列(原始或其他)。

我依旧记得在字符串中阅读有关此方法的具体方法,但我不记得算法的名称。我可以轻松地写一些方法来做到这一点,但我知道有一个很好的解决方案,这是我的舌尖。如果有一些.Net方法可以做到这一点,我也会这样做(尽管为了教育,我仍然会欣赏搜索算法的名称)。

2 个答案:

答案 0 :(得分:3)

您可以使用LINQ执行此操作,如下所示:

var res = Enumerable.Range(0, large.Length-1)
    .Cast<int?>()
    .FirstOrDefault(n => large.Skip(n.Value).Take(small.Length).SequenceEqual(small));
if (res != null) {
    Console.Println("Found at {0}", res.Value);
} else {
    Console.Println("Not found");
}

除了Cast<int?>部分之外,该方法是不言自明的:你需要它来决定在large数组的初始位置找到结果,何时返回零,而不是找到结果,当返回为null时。

这是demo on ideone

上述内容的复杂性为O(M*N),其中MNlargesmall数组的长度。如果large数组非常长,并且包含与small的长前缀匹配的大量“几乎正确”的子序列,那么最好使用高级算法来搜索序列,例如作为Knuth–Morris–Pratt (KMP) algorithm。 KMP算法通过观察发生不匹配的情况来加速搜索,small序列包含足够的信息,指示您可以根据小序列中的位置在large序列中移动多远。第一次不匹配。为small序列准备了一个查找表,然后在整个搜索过程中使用该表来决定如何推进搜索点。 KMP的复杂性为O(N+M)。请参阅上面链接的维基百科文章,了解KMP算法的伪代码。

答案 1 :(得分:0)

你在考虑Lambda表达式吗?当你用字符串说一个更具体的方法时,我想到了这一点。

http://www.dotnetperls.com/array-find

相关问题