假设我有一个很大的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方法可以做到这一点,我也会这样做(尽管为了教育,我仍然会欣赏搜索算法的名称)。
答案 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
时。
上述内容的复杂性为O(M*N)
,其中M
和N
是large
和small
数组的长度。如果large
数组非常长,并且包含与small
的长前缀匹配的大量“几乎正确”的子序列,那么最好使用高级算法来搜索序列,例如作为Knuth–Morris–Pratt (KMP) algorithm。 KMP算法通过观察发生不匹配的情况来加速搜索,small
序列包含足够的信息,指示您可以根据小序列中的位置在large
序列中移动多远。第一次不匹配。为small
序列准备了一个查找表,然后在整个搜索过程中使用该表来决定如何推进搜索点。 KMP的复杂性为O(N+M)
。请参阅上面链接的维基百科文章,了解KMP算法的伪代码。
答案 1 :(得分:0)
你在考虑Lambda表达式吗?当你用字符串说一个更具体的方法时,我想到了这一点。