C# 对 byte 数组进行模式搜索
本文告诉大家几个方法从 byte 数组找到对应的相同序列的数组
最简单的方法是进行数值判断,但是代码最少是使用Linq ,效率比较高是使用 Boyer-Moore 算法,下面就告诉大家几个算法的代码
判断数值
class ByteArrayRocks
{
public static IEnumerable<int> IndexOf(byte[] source, int start, byte[] pattern)
{
if (IsEmptyLocate(source, start, pattern))
{
yield break;
}
for (int i = start; i < source.Length; i++)
{
if (!IsMatch(source, i, pattern))
{
continue;
}
yield return i;
}
}
private static readonly int[] Empty = new int[0];
private static bool IsMatch(byte[] array, int position, byte[] candidate)
{
if (candidate.Length > (array.Length - position))
{
return false;
}
for (int i = 0; i < candidate.Length; i++)
{
if (array[position + i] != candidate[i])
{
return false;
}
}
return true;
}
private static bool IsEmptyLocate(byte[] array, int start, byte[] candidate)
{
return array == null
|| candidate == null
|| array.Length == 0
|| array.Length < start
|| candidate.Length == 0
|| candidate.Length + start > array.Length;
}
}
这是最简单的方法,参见 https://stackoverflow.com/a/283648/6116637
linq
这个方法的代码最少
class LinqArraySearch
{
public static IEnumerable<int> IndexOf(byte[] source, int start, byte[] pattern)
{
for (int i = start; i < source.Length; i++)
{
if (source.Skip(i).Take(pattern.Length).SequenceEqual(pattern))
{
yield return i;
}
}
}
}
Boyer-Moore-Horspool 搜索
这是最快的方法
class BoyerMooreHorspool
{
public static IEnumerable<long> IndexesOf(byte[] source, int start, byte[] pattern)
{
if (source == null)
{
throw new ArgumentNullException(nameof(source));
}
if (pattern == null)
{
throw new ArgumentNullException(nameof(pattern));
}
long valueLength = source.LongLength;
long patternLength = pattern.LongLength;
if ((valueLength == 0) || (patternLength == 0) || (patternLength > valueLength))
{
yield break;
}
var badCharacters = new long[256];
for (var i = 0; i < 256; i++)
{
badCharacters[i] = patternLength;
}
var lastPatternByte = patternLength - 1;
for (long i = 0; i < lastPatternByte; i++)
{
badCharacters[pattern[i]] = lastPatternByte - i;
}
long index = start;
while (index <= valueLength - patternLength)
{
for (var i = lastPatternByte; source[index + i] == pattern[i]; i--)
{
if (i == 0)
{
yield return index;
break;
}
}
index += badCharacters[source[index + lastPatternByte]];
}
}
}
参见:https://stackoverflow.com/q/16252518/6116637
测试了三个方法的性能,请看下面
BenchmarkDotNet=v0.10.14, OS=Windows 10.0.17134
Intel Core i7-6700 CPU 3.40GHz (Skylake), 1 CPU, 8 logical and 4 physical cores
.NET Core SDK=2.1.202
[Host] : .NET Core 2.0.9 (CoreCLR 4.6.26614.01, CoreFX 4.6.26614.01), 64bit RyuJIT
DefaultJob : .NET Core 2.0.9 (CoreCLR 4.6.26614.01, CoreFX 4.6.26614.01), 64bit RyuJIT
| Method | Mean | Error | StdDev |
|---|---|---|---|
| Linq | 13,332.8 us | 251.782 us | 466.694 us |
| ByteArrayRocks | 371.3 us | 7.327 us | 14.462 us |
| BoyerMooreHorspool | 108.3 us | 1.153 us | 1.079 us |
其他方法请看下面
使用不安全代码的 Boyer Moore 算法 C# High Performance Boyer Moore Byte Array Search Algorithm
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入
我搭建了自己的博客 https://blog.lindexi.com/ 欢迎大家访问,里面有很多新的博客。只有在我看到博客写成熟之后才会放在csdn或博客园,但是一旦发布了就不再更新
如果在博客看到有任何不懂的,欢迎交流,我搭建了 dotnet 职业技术学院 欢迎大家加入

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接:http://blog.csdn.net/lindexi_gd ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请与我联系。
C# 对 byte 数组进行模式搜索的更多相关文章
- go语言:多个[]byte数组合并成一个[]byte
场景:在开发中,要将多个[]byte数组合并成一个[]byte,初步实现思路如下: 1.获取多个[]byte长度 2.构造一个二维码数组 3.循环将[]byte拷贝到二维数组中 package gst ...
- byte数组和File,InputStream互转
1.将File.FileInputStream 转换为byte数组: File file = new File("file.txt"); InputStream input = n ...
- C# byte数组与Image的相互转换
功能需求: 1.把一张图片(png bmp jpeg bmp gif)转换为byte数组存放到数据库. 2.把从数据库读取的byte数组转换为Image对象,赋值给相应的控件显示. 3.从图片byte ...
- 透过byte数组简单分析Java序列化、Kryo、ProtoBuf序列化
序列化在高性能网络编程.分布式系统开发中是举足轻重的之前有用过Java序列化.ProtocolBuffer等,在这篇文章这里中简单分析序列化后的byte数组观察各种序列化的差异与性能,这里主要分析Ja ...
- 字符串与byte数组转换
string weclome=""; byte[] data = new byte[1024]; //字符串转byte数组 data = Encoding.ASCII.GetByt ...
- C# 将文件转化成byte[]数组
/// <summary> /// 将文件转换成byte[] 数组 /// </summary> /// <param name="fileUrl"& ...
- Java 文件和byte数组转换
/** * 获得指定文件的byte数组 */ private byte[] getBytes(String filePath){ byte[] buffer = null; try { File fi ...
- InputStream,BufferedImage与byte数组之间的转换
需要获取网络的一张图片,但是某种需要,要把获取的这段流输入换为BufferedImage流,有的地方还需要转换为byte[]. 获得图片地址,获得了一个图片输入流,例如: Url img = n ...
- php byte数组与字符串转换类
<?php /** * byte数组与字符串转化类 * @author ZT */ class Bytes { /** * 转换一个string字符串为byte数组 * @param $str ...
随机推荐
- 【JZOJ4919】【NOIP2017提高组模拟12.10】神炎皇
题目描述 神炎皇乌利亚很喜欢数对,他想找到神奇的数对. 对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对.请问这样的数对共有多少呢? 数据范围 对于100%的数 ...
- 【JZOJ4747】【NOIP2016提高A组模拟9.3】被粉碎的线段树
题目描述 输入 第一行包括两个正整数,N ,M ,分别表示线段树的宽以及询问次数. 以下N-1 行以先序遍历(dfs深搜顺序)描述一个小R线段树,每行一个正整数表示当前非叶子节点的 mid,保证每个节 ...
- @codeforces - 1276F@ Asterisk Substrings
目录 @description@ @solution@ @accepted code@ @details@ @description@ 给定一个包含 n 个小写字母的字符串 s,用 s 生成 n 个串 ...
- 【JZOJ4882】【NOIP2016提高A组集训第12场11.10】多段线性函数
题目描述 数据范围 解法 三分找出极值,两个二分找出极值的范围. 代码 #include<iostream> #include<stdio.h> #include<str ...
- hdu2041 dp
#include<stdio.h> int main() { int i,t,n; ]; dp[]=; dp[]=; dp[]=; ;i<=;i++) dp[i]=dp[i-]+dp ...
- php7 新内容
1.use增强 以thinkphp5.0为例 namespace app\home\controller;use think\{Loader,Controller,Captcha,Request}; ...
- Java练习 SDUT-3338_计算各种图形的周长(接口与多态)
计算各种图形的周长(接口与多态) Time Limit: 1000 ms Memory Limit: 65536 KiB Problem Description 定义接口Shape,定义求周长的方法l ...
- *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '[<_UIFeedbackParameters 0x1d4442e50> setNilValueForKey]: could not set nil as the value for the key rate.'
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '[<_UIFeedbac ...
- 阿里云DataV专业版发布,为可视化创造更多可能!
阿里云数据可视化应用工具DataV正式推出专业版,该版本为可视化领域专业团队和从业者量身打造,定位数据可视分析大屏搭建场景,让使用者可以轻松hold住复杂交互设计和实时数据交互查询需求. 什么是Dat ...
- 模板—BSGS
#include<iostream> #include<cstdio> #include<cmath> #include<map> #define LL ...