C# C中的strstr()等价物#
我有两个C# C中的strstr()等价物#,c#,.net,arrays,algorithm,strstr,C#,.net,Arrays,Algorithm,Strstr,我有两个字节[],我想在第一个字节[]中找到第二个字节[]的第一个匹配项(或其中的一个范围) 我不想使用字符串来提高效率(将第一个字节[]转换为字符串将是低效的) 基本上,我相信这就是strstr()在C中所做的 实现这一点的最佳方法是什么(因此它是高效且易于使用的) 它应该是这样的: int GetOffsetOfArrayInArray(byte[] bigArray, int bigArrayOffset, int bigArrayCount, byte[] smallArray); 谢
字节[]
,我想在第一个字节[]
中找到第二个字节[]
的第一个匹配项(或其中的一个范围)
我不想使用字符串来提高效率(将第一个字节[]
转换为字符串将是低效的)
基本上,我相信这就是strstr()
在C中所做的
实现这一点的最佳方法是什么(因此它是高效且易于使用的)
它应该是这样的:
int GetOffsetOfArrayInArray(byte[] bigArray, int bigArrayOffset, int bigArrayCount, byte[] smallArray);
谢谢
更新:
我想要一个比简单搜索更有效的解决方案。这意味着应该使用比较缓冲区更有效的事实-memcmp()比在字节上迭代更有效
另外,我知道有一些算法可以优化这样的场景:
- 大数组:“12351231234”
- 小阵:“1234”
- 朴素算法:7比较发现“1235”与“1231234”不同,2比较发现下一个“1”,4比较发现“1235”与“1231”不同,3比较发现下一个“1”,7比较发现匹配。总共7+2+4+3+7=23
- 智能算法:7比较发现“1235”与“1231234”不同,直接跳到下一个“1”(不进行比较),4比较发现“1235”与“1231”不同,直接跳到“5”之外,7比较发现匹配。总共有7+4+7=18个比较
int GetOffsetOfarrayArray(字节[]bigArray,int bigArrayOffset,
int bigArrayCount,字节[]smallArray)
{
字节第一=小数组[0];
bool cont=真;
而(续&)
bigArrayOffset=Array.IndexOf(bigArray,first,bigArrayOffset)!=-1)
{
if(bigArrayOffset+smallArray.Length>bigArray.Length)
{
bigArrayOffset=-1;
打破
}
cont=假;
对于(int i=1;i
更新;(希望)修复了Henk提醒我的问题
更新2:解决原始问题的更新:
int GetOffsetOfArrayInArray(byte[] bigArray, int bigArrayOffset,
int bigArrayCount, byte[] smallArray)
{
int bigArrayEnd = Math.Min(bigArrayCount + bigArrayOffset, bigArray.Length)
byte first = smallArray[0];
bool cont= true;
while (cont &&
bigArrayOffset=Array.IndexOf(bigArray, first, bigArrayOffset) != -1)
{
int bookmark = bigArrauOffset + 1;
bool bookmarkset = false;
if (bigArrayOffset + smallArray.Length > bigArrayEnd )
{
bigArrayOffset = -1;
break;
}
cont= false;
for(int i=1; i< smallArray.Length; ++i)
{
if (!bookmarkset && bigArray[bigArrayOffset+i] == first)
{
bookmark = bigArrayOffset+i;
bookmarkset = true;
}
if (bigArray[bigArrayOffset+i] != smallArray[i])
{
bigArrayOffset = bookmark;
cont = true;
break;
}
}
}
return bigArrayOffset;
}
int getOffsetOfarrayArray(字节[]bigArray,int bigArrayOffset,
int bigArrayCount,字节[]smallArray)
{
int bigArrayEnd=Math.Min(bigArrayCount+bigArrayOffset,bigArray.Length)
字节第一=小数组[0];
bool cont=真;
而(续&)
bigArrayOffset=Array.IndexOf(bigArray,first,bigArrayOffset)!=-1)
{
int bookmark=bigArrauOffset+1;
booklbookmarkset=false;
if(bigArrayOffset+smallArray.Length>bigArrayEnd)
{
bigArrayOffset=-1;
打破
}
cont=假;
对于(int i=1;i
我没有任何代码可供您使用,但您将找到的最快解决方案的名称是算法。它可以比O(n)做得更好
是CodeProject上字符串的实现。看起来转换到字节[]
应该不会太难。以下是我对解决方案的看法。它一分为二。第一部分主要是寻找一个可能的起点。如果找到一个,它将从两端比较列表(以降低循环计数,这基本上是一个没有分析器的微优化,但通常更快)
int GetOffsetOfarrayArray(字节[]bigArray,
int bigArrayOffset,
int BigarayCount,
字节[]小数组)
{
var length=smallArray.length;
var lastPossibleStart=bigArray.Length-Length;
var startByte=smallArray[0];
for(var first=bigArrayOffset;first 对于算法理论中的(var i=first;smallIndex,众所周知,优化速度会消耗内存,反之亦然。我的算法使用更多的内存(不是很多),但反过来只扫描大数组一次
public static int GetOffsetOfArrayInArray(byte[] bigArray, int bigArrayOffset, int bigArrayCount, byte[] smallArray)
{
// TODO: Check whether none of the variables are null or out of range.
if (smallArray.Length == 0)
return 0;
List<int> starts = new List<int>(); // Limited number of elements.
int offset = bigArrayOffset;
// A single pass through the big array.
while (offset < bigArrayOffset + bigArrayCount)
{
for (int i = 0; i < starts.Count; i++)
{
if (bigArray[offset] != smallArray[offset - starts[i]])
{
// Remove starts[i] from the list.
starts.RemoveAt(i);
i--;
}
else if (offset - starts[i] == smallArray.Length - 1)
{
// Found a match.
return starts[i];
}
}
if (bigArray[offset] == smallArray[0] &&
offset <= (bigArrayOffset + bigArrayCount - smallArray.Length))
{
if (smallArray.Length > 1)
// Add the start to the list.
starts.Add(offset);
else
// Found a match.
return offset;
}
offset++;
}
return -1;
}
public static int getOffsetOfarrayArray(字节[]bigArray,int bigArrayOffset,int bigArrayCount,字节[]smallArray)
{
//TODO:检查所有变量是否为null或超出范围。
if(smallArray.Length==0)
返回0;
List start=new List();//元素数量有限。
int offset=bigArrayOffset;
//一次通过大阵列。
而(偏移量int GetOffsetOfArrayInArray(byte[] bigArray,
int bigArrayOffset,
int bigArrayCount,
byte[] smallArray)
{
var length = smallArray.Length;
var lastPossibleStart = bigArray.Length - length;
var startByte = smallArray[0];
for (var first = bigArrayOffset; first < lastPossibleStart; first++)
{
if (bigArray[first] == startByte &&
check(bigArray, smallArray, first, length))
{
return first;
}
}
return -1;
}
bool check(byte[] bigArray, byte[] smallArray, int first, int length)
{
var smallIndex = 0;
var smallLast = length - 1;
var last = first + length - 1;
for (var i = first; smallIndex <= smallLast; i++)
{
if (bigArray[i] != smallArray[smallIndex] ||
bigArray[last] != smallArray[smallLast])
{
return false;
}
smallIndex = i - first + 1;
last--;
smallLast--;
}
return true;
}
}
public static int GetOffsetOfArrayInArray(byte[] bigArray, int bigArrayOffset, int bigArrayCount, byte[] smallArray)
{
// TODO: Check whether none of the variables are null or out of range.
if (smallArray.Length == 0)
return 0;
List<int> starts = new List<int>(); // Limited number of elements.
int offset = bigArrayOffset;
// A single pass through the big array.
while (offset < bigArrayOffset + bigArrayCount)
{
for (int i = 0; i < starts.Count; i++)
{
if (bigArray[offset] != smallArray[offset - starts[i]])
{
// Remove starts[i] from the list.
starts.RemoveAt(i);
i--;
}
else if (offset - starts[i] == smallArray.Length - 1)
{
// Found a match.
return starts[i];
}
}
if (bigArray[offset] == smallArray[0] &&
offset <= (bigArrayOffset + bigArrayCount - smallArray.Length))
{
if (smallArray.Length > 1)
// Add the start to the list.
starts.Add(offset);
else
// Found a match.
return offset;
}
offset++;
}
return -1;
}