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