C# 用其他子阵列替换所有子阵列的高效算法

C# 用其他子阵列替换所有子阵列的高效算法,c#,algorithm,search,replaceall,C#,Algorithm,Search,Replaceall,我有一个字节数组(可以非常大,超过3200万字节),我需要用相同长度的其他子数组替换一些子数组。 我目前的方法是在字节数组中搜索我需要替换的所有子数组,每次我找到一个子数组时,将子数组的索引添加到列表中,然后继续。 我的代码如下。我有一种烦人的感觉,这是不可能有效率的,因为3200万字节需要超过10秒才能完成搜索和替换。我给它传递了8个字符串来替换,所以它基本上搜索了16个子数组。 有人看到我的算法有什么缺陷,还是有更有效的 顺便说一句,我并没有在代码中替换它们,只是找到索引。我的代码应该非

我有一个字节数组(可以非常大,超过3200万字节),我需要用相同长度的其他子数组替换一些子数组。 我目前的方法是在字节数组中搜索我需要替换的所有子数组,每次我找到一个子数组时,将子数组的索引添加到列表中,然后继续。

我的代码如下。我有一种烦人的感觉,这是不可能有效率的,因为3200万字节需要超过10秒才能完成搜索和替换。我给它传递了8个字符串来替换,所以它基本上搜索了16个子数组。
有人看到我的算法有什么缺陷,还是有更有效的


顺便说一句,我并没有在代码中替换它们,只是找到索引。我的代码应该非常有效

 public class Search
{
    public List<int> positions;
    public List<int> lengths;
    private List<byte[]> stringsToSearchFor;
    public Search(List<string> strings){
        stringsToSearchFor = new List<byte[]>();
        positions = new List<int>();
        lengths = new List<int>();
        foreach (string tempString in strings){
            stringsToSearchFor.Add(Encoding.ASCII.GetBytes(tempString));
            stringsToSearchFor.Add(Encoding.Unicode.GetBytes(tempString));
        }
    }

    public void SearchBytes(byte[] haystack){
        int[] arrayOfInt = new int[stringsToSearchFor.Count];
        bool[] arrayOfBoolean = new bool[stringsToSearchFor.Count];
        for (var i = 0; i < haystack.Length; i++){
            byte currentByte = haystack[i];
            for (int stringCounter = 0; stringCounter < arrayOfBoolean.Length; stringCounter++)
            {
                byte[] stringLookFor = stringsToSearchFor.ElementAt(stringCounter);
                byte currentStringByte = stringLookFor[arrayOfInt[stringCounter]];
                //Saying the current byte is the desired one
                if (currentStringByte == currentByte)
                {
                    if (arrayOfInt[stringCounter] + 1 == stringLookFor.Length){
                        positions.Add(i - stringLookFor.Length + 1);
                        lengths.Add(stringLookFor.Length);
                        arrayOfInt[stringCounter] = 0;
                    }
                    else
                    {
                        arrayOfInt[stringCounter]++;
                    }
                }
                else
                {
                    arrayOfInt[stringCounter] = 0;
                }
            }
        }
        return;
    }



}
公共类搜索
{
公开名单职位;
公开名单长度;
私人列表搜索;
公共搜索(列表字符串){
stringsToSearchFor=新列表();
位置=新列表();
长度=新列表();
foreach(字符串中的字符串tempString){
添加(Encoding.ASCII.GetBytes(tempString));
添加(Encoding.Unicode.GetBytes(tempString));
}
}
公共void SearchBytes(byte[]haystack){
int[]arrayOfInt=new int[stringsToSearchFor.Count];
bool[]arrayOfBoolean=新bool[stringsToSearchFor.Count];
对于(var i=0;i
您基本上是在进行暴力搜索。你可以做一些更类似于或字符串搜索算法的事情,而不是使用蛮力搜索(但不是在字符串中搜索字符序列,而是在数组中搜索字节序列)。

你基本上是在使用蛮力搜索。你可以做一些更类似于或字符串搜索算法的事情,而不是使用暴力(但不是在字符串中搜索字符序列,而是在数组中搜索字节序列)。

我可以从
SearchBytes()
只有两个嵌套的
循环,该蛮力搜索算法存在缺陷。这种蛮力搜索需要3个嵌套循环:对于干草堆中的每个起始位置,对于每个针串,需要一个循环来检查整个针是否出现在干草堆中的该位置。(如果发现字符不匹配,最内层循环可能会提前中止。)

这里有一个具体的例子:如果干草堆是
ABCABD
,而您的一根针串是
ABCABD
,那么该串将不会被找到,尽管它确实发生了。这是因为一旦你的算法在干草堆中看到第二个
C
,它就会得出结论,它必须从干草堆中的当前位置开始寻找针,而实际上它需要从更早的位置开始寻找


无论如何,在长度为n的草堆串中搜索单个长度为m的针串时,蛮力的时间复杂度为O(nm),如果两者都是中等长度,这是非常可怕的,如果您要查找几个大字符串,那么运行这两种方法中的任何一种肯定会加快速度(并且是正确的:-P),但是专门针对在字符串中高效查找多个字符串的算法称为。它需要时间O(n+s+k),其中n是草堆大小,s是要搜索的针串大小之和,k是任何针串出现的次数,这很难被击败。

我可以从
SearchBytes()这一事实看出
只有两个嵌套的
循环,该蛮力搜索算法存在缺陷。这种蛮力搜索需要3个嵌套循环:对于干草堆中的每个起始位置,对于每个针串,需要一个循环来检查整个针是否出现在干草堆中的该位置。(如果发现字符不匹配,最内层循环可能会提前中止。)

这里有一个具体的例子:如果干草堆是
ABCABD
,而您的一根针串是
ABCABD
,那么该串将不会被找到,尽管它确实发生了。这是因为一旦你的算法在干草堆中看到第二个
C
,它就会得出结论,它必须从干草堆中的当前位置开始寻找针,而实际上它需要从更早的位置开始寻找

无论如何,在长度为n的草堆串中搜索单个长度为m的针串时,蛮力的时间复杂度为O(nm),如果两者都是中等长度,这是非常可怕的,如果您正在查找几个大字符串,那么运行这两种方法中的任何一种都肯定会加快速度(并且是正确的:-P),但是专门针对在字符串中高效查找多个字符串的算法称为