Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C中的strstr()等价物#_C#_.net_Arrays_Algorithm_Strstr - Fatal编程技术网

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;
}