C#在表示字符串的大字节数组中查找子数组



在我的应用程序中,我需要打开一个文件,查找一个标记,然后根据该标记进行一些操作。但是!文件内容将每个char与一个/0交替;代码";变为CCD_ 3(以十六进制字节表示(。

问题是终止符也是/0;CODE123";使用终止符会看起来像这样:

0x43 0x00 0x4F 0x00 0x44 0x00 0x45 0x00 0x31 0x00 0x32 0x00 0x33 0x00 0x00 0x00

由于/0是空字符串终止符,如果我使用File.ReadAllText(),我只得到垃圾,所以我尝试使用File.ReadAllBytes(),然后清除每个等于0的字节。这让我获得了可读的文本,但随后我会丢失数据何时结束的信息,即如果文件中有CODE123[terminator]PROP456[terminator]blablabla,我最终会得到CODE123PROP456blablabla。

因此,我决定将文件内容作为byte[]获取,然后查找另一个用内部数据为-/0的CODE初始化的byte[]。理论上这应该有效,但由于数据数组相当大(约150万个元素(,这需要太长时间。

蛋糕上的最后一个樱桃是,我正在寻找多次出现的CODE标签,所以我不能一找到它就去停下来。

我尝试修改这里发布的LINQ作为答案:在C中查找子数组的第一个出现/起始索引#如下所示:

var indices = (from i in Enumerable.Range(0, 1 + x.Length - y.Length)
where x.Skip(i).Take(y.Length).SequenceEqual(y)
select (int?)i).ToList();

但当我试图列举结果时,它就突然出现了。

所以,我的问题是:如何在一个大数组中高效地找到多个子数组?感谢

Matthew Wilson提出的奇妙的Boyer-Moore算法令人惊奇地解决了我的问题。

然后我不得不找到一个解决方案来查找实际的字符串终止,这看起来太特定于应用程序,对其他人来说没有用处,所以我没有发布它。如果你认为它可能有用,请告诉我,我会在这里发布它:(