buffer:array[0..255] of byte;
我要在这个数组中查找比如[$13,$0,$10,$0]一段数组该如何写算法,或者给个思路
当然我可以用 for do + if then 来实现,但如果要查找别的数组段就麻烦了

解决方案 »

  1.   

    写一个函数参数为两个数组:
    function GetArrFromArr(SourArr,NewArr:array of byte):integer;
    在其中用 for do + if then 查出NewArr在SourArr中的位置,然后返回,这样就是通用了,换别的数组也可以了
    如果还想对其他类型也适用可以重载一下
      

  2.   

    function SearchBuffer(Buffer: array of Byte;  SubBuffer: array of Byte;  iStart: Integer = 0): Integer;
    var
      iIndex : Integer;
      iLoop  : Integer;
      bFind  : Boolean;
    begin
      Result := -1;
      for iIndex := Low(Buffer) + iStart to High(Buffer) - Length(SubBuffer) + 1 do
      begin
        bFind := True;
        for iLoop := Low(SubBuffer) to High(SubBuffer) do
          if Buffer[iIndex + iLoop - Low(SubBuffer)] <> SubBuffer[iLoop] then
          begin
            bFind := False;
            break;
          end;
        if bFind then
        begin
          Result := iIndex;
          break;
        end;
      end;
    end;procedure TForm1.Button1Click(Sender: TObject);
    var
      Buffer: array [0..255] of byte;
      SubBuf: array [0..3] of Byte;
      iLoop : Integer;
      iPos  : Integer;
    begin
      for iLoop := Low(buffer) to High(buffer) do Buffer[iLoop] := iLoop;
      SubBuf[0] := 10;
      SubBuf[1] := 11;
      SubBuf[2] := 12;
      SubBuf[3] := 13;
      iPos := SearchBuffer(Buffer, SubBuf);
      if iPos <> -1 then
      begin
        ShowMessage (Format('Found at pos %d', [iPos]));
        //Search again
        iPos := SearchBuffer(Buffer, Buf, iPos + 1);
        if iPos <> -1 then
          ShowMessage (Format('Found at pos %d', [iPos]))
        else
          ShowMessage ('Not found');
      end
      else
        ShowMessage ('Not found');
    end;
      

  3.   

    我有一种思路,只不过,临时看来,数组元素不能有 $FF 这个值。当然,这个问题仔细想想也是可以解决的。我的思路如下:type
      TMyByteArr = Array[0..255] of Byte;function MySearch(var Buff : TMyByteArr; SubBuff : String) : integer;
    var
      I : integer;
    begin
      for I := Low(Buff) to High(Buff) do
        Buff[I] := Buff[I] +1;
      Result := Pos(SubBuff, StrPas(@Buff[Low(Buff)]));
      for I := Low(Buff) to High(Buff) do
        Buff[I] := Buff[I] -1;
    end;procedure TForm1.Button1Click(Sender: TObject);//测试一下
    var
      buffer : TMyByteArr;
      Found : integer;
      SubStr : string;
    begin
      Buffer[2] := $13;
      Buffer[3] := $0;
      Buffer[4] := $10;
      Buffer[5] := $0;
      Buffer[6] := $13;
      SubStr := Chr($14)+Chr($1)+Chr($11)+Chr($1);//注意,每个Byte要加1。这不难。
      Found := MySearch(Buffer, SubStr);
      showmessage(IntToStr(Found));
    end;
      

  4.   

    如果你要查找的连续元素个数是固定的,就有另一个思路:把这几个元素转换为一个与它长度相符的类型,然后循环搞定。如:4个元素,可以转换为LongInt(4字节)类型。
      

  5.   

    查找的元素不固定
    jadeluo(秀峰) 可以用
    再看看大家有什么想法
    下午结帖
      

  6.   

    上面说的思路的测试代码:procedure TForm1.Button1Click(Sender: TObject);
    var
      buffer : Array[0..255] of Byte;
      I : integer;
      SubStr : integer;
      P : ^integer;
    begin
      fillChar(Buffer, 256, 0);
      Buffer[2] := $13;
      Buffer[3] := $0;
      Buffer[4] := $10;
      Buffer[5] := $0;
      Buffer[6] := $13;
      SubStr := ($13 shl 24) + ($0 shl 16) + ($10 shl 8) + ($0);
      //SubStr := $13001000; //或者这样写
      for I := Low(Buffer) to High(Buffer)-3 do
        begin
        P := @Buffer[I];
        if P^ = SubStr then showmessage(IntToStr(I));
        end;
    end;
      

  7.   

    上面有一句写错了:
      SubStr := ($13) + ($0 shl 8) + ($10 shl 16) + ($0 shl 24);
      //SubStr := $00100013; //或者这样写
      

  8.   

    汗.......!!!!找到一个函数:CompareMem,直接用就行了!(我前面的一种思路实际上就是这种思路:内存块比较,如今找到这个函数了,就不用那么费事了。)procedure TForm1.Button1Click(Sender: TObject);
    var
      buffer : Array[0..255] of Byte;
      SubBuf : Array[0..3] of Byte;
      I : integer;
    begin
      fillChar(Buffer, 256, 0);//下面搞几个数据测试
      Buffer[2] := $13;
      Buffer[3] := $0;
      Buffer[4] := $10;
      Buffer[5] := $0;
      Buffer[6] := $18;  SubBuf[0] := $13;//这是要查找的连续元素,放在SubBuf里。
      SubBuf[1] := $0;
      SubBuf[2] := $10;
      SubBuf[3] := $0;
      for I := Low(Buffer) to High(Buffer) do
        if SysUtils.CompareMem(@Buffer[I], @SubBuf[0], SizeOf(SubBuf)) then
           ShowMessage('找到一段,起始处位于第' + inttostr(I) + '号元素');
    end;上面我用了定长数组。可以用动态数组的。
      

  9.   

    上面的调用,有一点点需要改正的地方:(下面是改正后)  for I := Low(Buffer) to High(Buffer)-SizeOf(SubBuf)+1 do
        if SysUtils.CompareMem(@Buffer[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then
           ShowMessage(Format('找到一段,起始处位于%d号元素',[I]));
    楼主及上面各位朋友,试一下 CompareMem 吧!其实就是 C/C++ 里的 memcmp 函数。实在是好用啊,直接对内存块进行比较。
      

  10.   

    根据楼上几位意见写的,大家看看还有什么需要改进
      function PosMemEx(subBuf, Buf : array of byte; Offset: Cardinal = 0):Integer;
      var
       bFind : Boolean;
       I     : Integer;
      begin
       Result:=-1;
       bFind:=False;
       for I := Low(Buf) + Integer(Offset) to High(Buf)-SizeOf(SubBuf)+1 do
        if SysUtils.CompareMem(@Buf[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then
        begin
          bFind:=true;
          break;
        end;
       if bFind then Result:=I;
      end;
      

  11.   

    function PosMemEx(subBuf, Buf : array of byte; Offset: Cardinal = 0):Integer;
      var
       I : Integer;
      begin
       Result:=-1;
       for I := Low(Buf) + Integer(Offset) to High(Buf)-SizeOf(SubBuf)+1 do
        if SysUtils.CompareMem(@Buf[I], @SubBuf[Low(SubBuf)], SizeOf(SubBuf)) then
        begin
          Result:=I;
          break;
        end;
      end;