C#数组子集获取
我有一个字节数组,我想确定这个字节数组的内容是否作为一个连续序列存在于另一个更大的数组中。最简单的方法是什么?最简单的方法是:C#数组子集获取,c#,algorithm,bytearray,search,C#,Algorithm,Bytearray,Search,我有一个字节数组,我想确定这个字节数组的内容是否作为一个连续序列存在于另一个更大的数组中。最简单的方法是什么?最简单的方法是: public static bool IsSubsetOf(byte[] set, byte[] subset) { for(int i = 0; i < set.Length && i + subset.Length <= set.Length; ++i) if (set.Skip(i).Take(subset.Le
public static bool IsSubsetOf(byte[] set, byte[] subset) {
for(int i = 0; i < set.Length && i + subset.Length <= set.Length; ++i)
if (set.Skip(i).Take(subset.Length).SequenceEqual(subset))
return true;
return false;
}
公共静态bool IsSubsetOf(字节[]集,字节[]子集){
对于(int i=0;i这是此答案的1/1端口:
这是一种非常有效的方法:
public static class KmpSearch {
public static int IndexOf(byte[] data, byte[] pattern) {
int[] failure = ComputeFailure(pattern);
int j = 0;
if (data.Length == 0) return -1;
for (int i = 0; i < data.Length; i++) {
while (j > 0 && pattern[j] != data[i]) {
j = failure[j - 1];
}
if (pattern[j] == data[i]) { j++; }
if (j == pattern.Length) {
return i - pattern.Length + 1;
}
}
return -1;
}
private static int[] ComputeFailure(byte[] pattern) {
int[] failure = new int[pattern.Length];
int j = 0;
for (int i = 1; i < pattern.Length; i++) {
while (j > 0 && pattern[j] != pattern[i]) {
j = failure[j - 1];
}
if (pattern[j] == pattern[i]) {
j++;
}
failure[i] = j;
}
return failure;
}
}
公共静态类KmpSearch{
公共静态int IndexOf(字节[]数据,字节[]模式){
int[]故障=计算故障(模式);
int j=0;
如果(data.Length==0)返回-1;
for(int i=0;i0&&pattern[j]!=data[i]){
j=故障[j-1];
}
if(pattern[j]==data[i]){j++;}
if(j==模式长度){
返回i-模式。长度+1;
}
}
返回-1;
}
私有静态int[]计算失败(字节[]模式){
int[]失败=新的int[pattern.Length];
int j=0;
for(int i=1;i0&&pattern[j]!=pattern[i]){
j=故障[j-1];
}
if(模式[j]==模式[i]){
j++;
}
失效[i]=j;
}
返回失败;
}
}
Michal:是O(n*m),它可能被认为是低效的,但是如果你担心跳过和取,不要这样。这和循环的一对一样有效。正如我所说,如果性能是一个问题,你应该考虑一个更高级的算法。@ Mehrdad -是的,但是MN对于二进制数据来说是相当大的……我知道SKIP()和是通过延迟执行完成的-所以它只是来自SequenceEquals的O(mn)的n个组件…性能将是一个问题,但现在我只想让我的代码工作。这应该做得很好…Skip()
实际上不能做索引跳转。它必须调用MoveNext()
在迭代器i
上。请查看原因。但是有了“如果您担心性能…做些其他事情”的警告,这个答案是正确的。