在我的应用程序中,我需要打开一个文件,查找一个标记,然后根据该标记进行一些操作。但是!文件内容将每个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算法令人惊奇地解决了我的问题。
然后我不得不找到一个解决方案来查找实际的字符串终止,这看起来太特定于应用程序,对其他人来说没有用处,所以我没有发布它。如果你认为它可能有用,请告诉我,我会在这里发布它:(