相关疑难解决方法(0)

什么是最快的子串搜索算法?

好吧,所以我听起来不像白痴我会更明确地陈述问题/要求:

  • 针(模式)和haystack(要搜索的文本)都是C样式的以空字符结尾的字符串.没有提供长度信息; 如果需要,必须计算.
  • 函数应该返回指向第一个匹配的指针,或者NULL如果找不到匹配项.
  • 不允许发生失败案件.这意味着任何具有非常量(或大常量)存储要求的算法都需要具有分配失败的后备情况(并且后备保养中的性能因此导致最坏情况的性能).
  • 实现是在C中,虽然没有代码的算法(或链接到这样的)的良好描述也很好.

......以及"最快"的意思:

  • 确定性O(n)where n= haystack长度.(但是O(nm)如果它们与更强大的算法组合以给出确定性O(n)结果,则可以使用通常(例如滚动哈希)算法的思想.
  • 从不执行(可测量;一些时钟if (!needle[1])等等)比天真蛮力算法更糟糕,特别是在非常短的针上,这可能是最常见的情况.(无条件的重预处理开销是不好的,因为试图以可能的针头为代价来改善病理针的线性系数.)
  • 给定任意针和干草堆,与任何其他广泛实现的算法相比,具有相当或更好的性能(不低于搜索时间长50%).
  • 除了这些条件,我将保留"最快"开放式的定义.一个好的答案应该解释为什么你认为你建议"最快"的方法.

我目前的实现比glibc实现的双向大约慢10%和8倍(取决于输入).

更新:我目前的最佳算法如下:

  • 对于长度为1的针,请使用strchr.
  • 对于长度为2-4的针,使用机器字一次比较2-4个字节,如下所示:在每次迭代时从大海捞针以16位或32位整数预加载针,并从大海捞针中循环旧字节输出/新字节.大海捞针的每个字节都只读取一次,并对0(字符串结束)和一个16位或32位比较进行检查.
  • 对于长度> 4的针,使用具有错误移位表的双向算法(如Boyer-Moore),该移位表仅应用于窗口的最后一个字节.为了避免初始化1kb表的开销,这对于许多中等长度的针来说是一个净损失,我保留一个位数组(32字节)标记移位表中的哪些条目被初始化.未设置的位对应于从不出现在针中的字节值,可以进行全针长度移位.

我脑海中留下的重大问题是:

  • 有没有办法更好地利用坏班次表?Boyer-Moore通过向后扫描(从右到左)充分利用它,但是双向扫描需要从左到右扫描.
  • 我在一般情况下找到的唯一两个可行的候选算法(没有内存或二次性能条件)是有序字母表上的双向字符串匹配.但是,是否存在易于检测的情况,其中不同的算法将是最佳的?当然,空间算法中的许多O(m)(其中m是针长)可以用于m<100左右.如果针对针的简单测试可能仅需要线性时间,那么也可以使用最坏情况二次方的算法.

奖励积分:

  • 假设针和干草堆都是结构良好的UTF-8,你能提高性能吗?(对于字节长度不同的字符,良好的形式在针和haystack之间强加了一些字符串对齐要求,并且当遇到不匹配的头字节时允许自动2-4字节移位.但这些约束是否会超出你的范围最大后缀计算,良好的后缀转换等已经为您提供了各种算法?)

注意:我很清楚那里的大多数算法,而不是它们在实践中的表现.这是一个很好的参考,所以人们不会继续给我作为评论/答案的算法参考:http://www-igm.univ-mlv.fr/~lecroq/string/index.html

c string algorithm substring

159
推荐指数
6
解决办法
7万
查看次数

在byte []中查找byte []和在string中查找字符串的速度 - 为什么后者更快?

我有一个任务,我需要在文件中查找序列.在进行测试应用程序时,我将文件读取为字符串(File.ReadAllText)并使用string.IndexOf来查找序列.当我尝试用字节实现相同的算法(将文件作为字节数组读取并在字节数组中查找字节数组)时,我注意到在byte []中查找byte []的速度大约是在字符串中查找字符串的3倍.我确保彻底检查它,完全相同的代码,一个使用byte []和其他使用字符串,执行时需要3倍 - 比如16s for byte vs~5s for string.

为了查找字节数组,我使用了这里描述的方法byte []数组模式搜索.为了查找字符串,我使用了字符串类的内置IndexOf函数.这是我尝试的byte []的IndexOf的一个实现:

    public int IndexOf(byte[] source, byte[] pattern, int startpos = 0)
    {
        int search_limit = source.Length - pattern.Length;
        for (int i = startpos; i < search_limit; i++)
        {
            if (source[i] == pattern[0])
            {
                bool found = true;
                for (int j = 1; j < pattern.Length; j++)
                {
                    if (source[i + j] != pattern[j])
                    {
                        found = false;
                        break;
                    }
                }
                if (found)
                    return i;
            } …
Run Code Online (Sandbox Code Playgroud)

c# string search byte bytearray

7
推荐指数
2
解决办法
1806
查看次数

使用另一个字节列表/数组计算字节列表/数组中的出现次数

我试图计算在另一个字节序列中字节序列发生的所有时间.但是,如果已经计算了它们,则无法重复使用字节.例如,给定字符串
k.k.k.k.k.k. 让我们假设字节序列是k.k它然后只发现3次而不是5次,因为它们会像下面那样被分解:[k.k].[k.k].[k.k].而不是像[k.[k].[k].[k].[k].k]它们在一圈的地方而且基本上只是向右移动2.

理想情况下,我们的想法是了解压缩字典或运行时编码的外观.所以目标就是获得

k.k.k.k.k.k. 只有2个部分,因为(kkk)是你可以拥有的最大和最好的符号.

到目前为止这是源:

using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.IO;


    static class Compression 
    {
        static int Main(string[] args)
        {

            List<byte> bytes = File.ReadAllBytes("ok.txt").ToList();
            List<List<int>> list = new List<List<int>>();

            // Starting Numbers of bytes - This can be changed manually.
            int StartingNumBytes = bytes.Count;
            for (int i = StartingNumBytes; i > 0; i--)
            {
                Console.WriteLine("i: " + i);

                for (int ii = 0; ii < bytes.Count …
Run Code Online (Sandbox Code Playgroud)

.net c# vb.net compression

6
推荐指数
1
解决办法
1874
查看次数

在字节数组中查找字节序列

我有一个字节数组,希望找到一些字节的"出现".

例如,00 69 73 6F 6D在一个非常大的字节数组(> 50/100兆字节)

要么

更好的反向操作:在不知道代码的情况下搜索最常见的模式,代码应该能够从文件中读取并找到它.

c# indexof

6
推荐指数
1
解决办法
2139
查看次数

加快字节数组中模式的查找速度

我有一个大约 70MB 的大型二进制文件。在我的程序中,我有一个方法可以根据文件查找byte[]数组模式,以查看它们是否存在于文件中。我有大约 1-1000 万个模式要针对该文件运行。我看到的选项如下:

  1. 将文件读入内存,然后byte[] file = File.ReadAllBytes(path)针对文件字节执行 byte[] 模式的 byte[] 查找。我已经使用了多种方法来执行此操作,例如: byte[] 数组模式搜索 在另一个数组中查找数组 (byte[])? 检查一个 byte[] 是否包含在另一个 byte[] 中的最佳方法尽管如此,当源大小很大时,查找速度非常慢byte[]byte[]在普通计算机上运行 100 万个模式需要数周时间。
  2. 将文件和模式转换为十六进制字符串,然后使用contains()执行查找的方法进行比较。这比byte[]查找更快,但将字节转换为十六进制会导致文件在内存中变大,从而导致更多的处理时间。
  3. Encoding.GetEncoding(1252).GetBytes()使用并执行查找将文件和模式转换为字符串。contains()然后,通过运行与执行查找的另一种方法的匹配来补偿二进制到字符串转换的限制(我知道它们不兼容)byte[](建议第一个选项)。这对我来说是最快的选择。

使用第三种方法(最快),100 万个模式将需要 2/3 天到一天的时间,具体取决于 CPU。我需要有关如何加快查找速度的信息。

谢谢。

编辑:感谢@MySkullCaveIsADarkPlace,我现在有了第四种方法,它比上述三种方法更快。我曾经使用有限的 byte[] 查找算法,现在我使用MemoryExtensions.IndexOf()byte[] 查找方法,该方法比上述三种方法稍快。尽管这种方法速度更快,但查找速度仍然很慢。1000 个模式查找需要 1 分钟。

每个模式为 12-20 字节。

c# arrays optimization performance

6
推荐指数
1
解决办法
801
查看次数

C#:有效地搜索大字符串以查找其他字符串的出现

我正在使用C#在大字符串中连续搜索多个字符串"关键字",这些字符串大于等于4kb.这段代码不断循环,睡眠不会在保持合理速度的同时降低CPU使用率.bog-down是关键字匹配方法.

我发现了一些可能性,并且它们都具有相似的效率.

1)http://tomasp.net/articles/ahocorasick.aspx- 我没有足够的关键字,因此这是最有效的算法.

2)正则表达式.使用实例级别,编译正则表达式. - 提供比我要求的更多功能,效率不够.

3)String.IndexOf. - 我需要做一个"智能"版本,因为它提供了足够的效率.循环遍历每个关键字并调用IndexOf不会削减它.

有谁知道我可以用来实现我的目标的任何算法或方法?

c# string

5
推荐指数
1
解决办法
6644
查看次数

确定字节数组是否包含特定顺序的字节

可能重复:
byte []数组模式搜索

假设我有一个字节数组:

byte[] myArray = new byte[]{1,2,3,4,5,6,7,1,9,3,4,3,4,7,6,5,6,7,8};
Run Code Online (Sandbox Code Playgroud)

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

我知道我可以这样做:

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

//then do  

s.Contains("9343")
Run Code Online (Sandbox Code Playgroud)

这不适用于长阵列.什么是更有效的方法呢?

c# arrays comparison

5
推荐指数
1
解决办法
6343
查看次数

在 C# 中将 Access 图像 OLE 对象转换为原始图像字节数组

我似乎无法为我的实际问题Invalid parameter when retretching image from DB所以我不能一块一块地尝试。在 C# 和 MS Access 2010 中使用 Visual Studio 2012。我的解决方案是一个与网络无关的应用程序。

我不确定这部分,所以这里我的问题是如何正确地将查询中的一行OLE对象的图像获取到字节数组( byte[]),因为这当然不是我的方式我用下面的代码来做。我所说的行是row["FOTO"]

                OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * FROM [APP_Equipamento_Geral] WHERE COD_ETIQ like '%" + codigo + "%'", l);
                DataSet ds = new DataSet();
                adapter.Fill(ds, "[APP_Equipamento_Geral]");
                string s = ds.Tables["[APP_Equipamento_Geral]"].Columns[16].ColumnName;
                foreach (DataRow row in ds.Tables["[APP_Equipamento_Geral]"].Rows)
                {
                    eq.NSerie = row["N_SERIE"].ToString();
                    eq.NInventario = row["Codigo"].ToString(); 

                    if (row["FOTO"] != DBNull.Value && row["FOTO"] != null)
                    {
                        string str = row["FOTO"].ToString();
                        byte[] …
Run Code Online (Sandbox Code Playgroud)

c# arrays ms-access datarow ms-access-2010

3
推荐指数
1
解决办法
7300
查看次数

以正确的方式从二进制文件中提取存储的png图像

我有二进制文件,每次包含每个PNG文件(二进制文件不是DLL,不是EXE,没什么常见的,只是包含不同文本信息的文件,PNG文件和其他一些东西.格式文件对我来说是未知的.PNG文件可以显示一个执行此类文件的程序).我没有这个程序的来源做这些文件.我的任务是从二进制文件中提取此PNG文件以显示它或将其保存为PNG.我写了一个代码,它可以处理这些文件中的一部分(比如大约50%的文件),但不是.在不工作的文件上,创建此文件的程序仍然可以显示包含的图像,因此图像在每个文件内部确实有效 - 但无论如何我的代码对某些文件不起作用.

有些图像似乎可能有另一种格式,可能是编码类型(我已尝试过所有不同的编码类型,没有成功).这是我的代码(我希望有人可以告诉我改变什么,图像变得可读).

我的代码是什么:它找到PNG图像"‰PNG"的已知起始字符串和已知的结束字符串"IEND®B`".这个字符串在我的任何二进制文件中都包含PNG.然后我的代码获取开始和结束之间的字符串+开始和结束序列,并使用Encoding.Default将其保存到文件中.大多数通过这种方式提取的PNG文件可以使用图像查看器显示,但大约50%是无效的.如果我用编辑器打开它并将字符与工作图像进行比较,则图像看起来没问题.Sofar我不知道哪个符号是错误图像格式的原因.

如果需要我会提供更多信息,这里是我的代码:

private void button2_Click(object sender, EventArgs e)
    {
        string ReadFile1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "file.dat");
        string WriteFile1 = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "test.png");
        string TMP = File.ReadAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), ReadFile1), Encoding.Default); //System.Text.Encoding.GetEncoding(1251)
        int start1 = TMP.IndexOf("PNG", 0 ,StringComparison.Ordinal);
        if (start1 == 0) { return; }
        int end1 = TMP.IndexOf("IEND", StringComparison.Ordinal);
        string PNG = TMP.Substring(start1 - 1, (end1 + 9) - start1);
        File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "test.png"), PNG, Encoding.Default);
    }
Run Code Online (Sandbox Code Playgroud)

我还首先考虑使用二进制方法获取PNG并使用此代码,但我只是读取字符串时得到了完全相同的结果.这是我早期的代码.我使用字符串来搜索字节数组中的位置进行比较.我对二进制代码没有运气...

 byte[] by;
        // 1.
        // Open file with a BinaryReader.
        using (BinaryReader b = new …
Run Code Online (Sandbox Code Playgroud)

c# binary png binaryfiles binary-data

2
推荐指数
2
解决办法
4766
查看次数