【问题标题】:determine if array of bytes contains bytes in a specific order [duplicate]确定字节数组是否包含特定顺序的字节[重复]
【发布时间】:2011-11-24 16:55:56
【问题描述】:

可能重复:
byte[] array pattern search

假设我有一个字节数组:

byte[] myArray = new byte[]{1,2,3,4,5,6,7,1,9,3,4,3,4,7,6,5,6,7,8};

如何确定 myArray 是否按该顺序包含字节 9、3、4、3?我是否必须遍历将每个元素附加到字符串的数组,然后使用 String.Contains() 方法来知道该字节数组是否按该顺序包含这些元素?

我知道我可以这样做:

String s = "";
foreach(byte b in myArray)
{
  s = s + b.ToString();
}

//then do  

s.Contains("9343")

这在长数组上效率不高。什么是更有效的方法?

【问题讨论】:

  • 如果您正在考虑制作一个字符串来执行包含:字符串 myString = System.Text.Encoding.ASCII.GetString(myByteArray ) 但等待正确答案 ;-)
  • 我不需要将其转换为字符串。我只是使用了一个字符串,因为这是我所知道的唯一可以让我进行这种类型比较的方法。这很有用,但非常感谢
  • 真的有一个类似的问题抱歉我没找到。

标签: c# arrays comparison


【解决方案1】:

试试下面的

public static bool ContainsSequence(byte[] toSearch, byte[] toFind) {
  for (var i = 0; i + toFind.Length < toSearch.Length; i++) {
    var allSame = true;
    for (var j = 0; j < toFind.Length; j++) {
      if (toSearch[i + j] != toFind[j]) {
        allSame = false;
        break;
      }
    }

    if (allSame) {
      return true;
    }
  }

  return false;
}

【讨论】:

  • 在我的快速测试中,这有一个错误。如果要查找的数据是数组中的最后一个元素,则它会提前退出循环。我会做更多的测试来验证这一点并发布答案,但现在它基本上是把第一个循环条件改为&lt;=
  • 这需要更改为“for (var i = 0; i + toFind.Length
【解决方案2】:

最简单的有效算法是遍历字节数组,直到在要查找的字节模式中的第一个字节上找到匹配项,然后遍历这两个字节直到到达末尾,或者如果您找到一个不匹配的地方,从你离开的地方继续。如果您继续获得部分匹配,这可能会“降级”。根据您的需要,这可能就足够了(编写简单,维护简单)。

如果这还不够快,您可以轻松采用Boyer-Moore

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-13
    • 2021-07-02
    • 1970-01-01
    相关资源
    最近更新 更多