现在我有一个类似下面这样的字符串(共240个字符),其中我需要获取若干个第m位开始n个字符长的内容,求最佳解法。例如:const
    str:='432423480580345723479054280548……7349729340';{公240位}我要取得第
    
    <1>8位开始,4个字符长的子串;
    <2>16位后,2个字符长的子串;
    <3>……
    <i>第k位开始,s个字符长的子串。由于我这里是工业控制方面的系统,因此对时间、空间性能要求很高,希望各位大虾多多援手。

解决方案 »

  1.   

    var
      p:array[m..n] of char;
      i:integer;
    begin
      for i:=m ot n do begin
        p[m]=str[m];end;
      

  2.   

    还要判断一下M,N的范围,如果M<0,N>240则出错.
      

  3.   

    可以STR2:=COPY(STR1,M,N)啊
      

  4.   

    function SubStr(AStr: String; AFrom, ACount: Integer): String;
    begin
       result := '';
       if (ACount > 0) and (AFrom > 0) and (AFrom <= Length(AStr)) then
       begin
          if ACount > Length(AStr) - AFrom + 1 then
             ACount := Length(AStr) - AFrom + 1; 
          SetLength(result, ACount);
          Move(AStr[AFrom], result[1], ACount);
       end;
    end;
      

  5.   

    kyee(浪子阿鹏) 哥哥给的方法我实验过,但是所用的时间还是太长,谁能再优化一下呀?马上我就得回公司了,也不能总在外地呆着呀,会被开除的(呵呵,后半句是玩笑)。但是也不能不给客户做完哪。
      

  6.   

    TO:hottey(蓝色的幽灵)     很痛苦,没有规律,但是也可以说是有规律,因为第一次定下来以后,就不再改变了。
      

  7.   

    我现在写了如下一个函数:Type 
      TVDataList = Record
        rst1:Array [8..9] of Char;
        rst2:Array [10..15] of Char;
        ……
        rstk:Array [m..n] of Char;
      End;
    Function GetResultDataList(strSource : String) : TStrings
    var
      dlDes : TVDataList;
      pStr  : PChar;
      slTemp: TStringList;
    begin
      pStr:=@dlDes;
      strCopy(pStr,PChar(strSource));
      Result.Add(rst1);
      Result.Add(rst2);
      ……
      Result.Add(rstk);
      if Not(Result.Count > 0) then
        begin
          Raise Exception.Create('字符拆分过程出现错误');
          exit;
        end;
    end;我觉得这已经是够快的方法了,但是还是不行,还是不够快,真不成让我嵌汇编????
      

  8.   

    // 改进一下, 尺寸和起始位置不做判断, 也不动态分配内存, 这样速度就快很多了.
    function SubStr(AStr: String; var ADest: ShortString;
                    AFrom, ACount: Integer): Integer;
    begin
       // 判断尺寸, 这一段在已知情况下可以省略.
       {if ACount > Length(AStr) - AFrom + 1 then
          ACount := Length(AStr) - AFrom + 1;
       if ACount > 255 then
          ACount := 255;}   //result := 0;
       //if ACount > 0 then
       //begin
          Move(AStr[AFrom], ADest[1], ACount);
          ADest[0] := Char(ACount);
          result := ACount;
       //end;
    end;// 注: str 是已经的串
    procedure DivideString;
    var
       strBuffer: ShortString;
    begin
       // 第 1 子串
       SubStr(str, strBuffer, 8, 4);
       //WriteSubStrToTarget(strBuffer);   // 第 2 子串
       SubStr(str, strBuffer, 16, 2);
       //WriteSubStrToTarget(strBuffer);   // 第 3 子串
       // ... ...   // 第 i 子串
       SubStr(str, strBuffer, k, s);
       //WriteSubStrToTarget(strBuffer);
    end;不妨再试一次, 如何?
      

  9.   

    // 若还不能解决, 现在也只有最后一招了.
    // 已知存放子串的数组
    // arrSub1: array[0..4] of Char;
    // arrSub2: array[0..2] of Char;
    // ...
    // arrSubi: array[0..s] of Char;
    procedure DivideString;
    begin
       // 第 1 子串
       Move(str[8], arrSub1, 4);
       arrSub1[4] := #0;   // 第 2 子串
       Move(str[16], arrSub2, 2);
       arrSub1[2] := #0;   // 第 3 子串
       // ... ...   // 第 i 子串
       Move(str[k], arrSubi, s);
       arrSub1[s] := #0;
    end;
      

  10.   

    // 刚才有错.
    // 若还不能解决, 现在也只有最后一招了.
    // 已知存放子串的数组
    // arrSub1: array[0..4] of Char;
    // arrSub2: array[0..2] of Char;
    // ...
    // arrSubi: array[0..s] of Char;
    procedure DivideString;
    begin
       // 第 1 子串
       Move(str[8], arrSub1, 4);
       arrSub1[4] := #0;   // 第 2 子串
       Move(str[16], arrSub2, 2);
       arrSub2[2] := #0;   // 第 3 子串
       // ... ...   // 第 i 子串
       Move(str[k], arrSubi, s);
       arrSubi[s] := #0;
    end;
      

  11.   

    提供目前最快样例,欢迎改进,如有比这更好更优的,
    该测试结果:经运行 约3.3 /100000*20 组
    机器配置:cpu:piii 1G 512内存  delphi7function TForm1.SubStr1(const sStr: String;Const AFrom, ACount: Byte; var dStr:String): integer;
    var
      i,j:Byte;
    begin
      if AFrom+ACount<255 then
      begin
        SetLength(dStr,ACount);
        For i:=1 to ACount  do
        dStr[i] := sStr[AFrom+i-1] ;
      end;
    end;
    procedure TForm1.Test;
    var
       S: ShortString;
       subS1,subS2:string;
       d1,d2:Tdatetime;
       k:integer;
    begin
       S := '1234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890121234567890234567890134567890124444';
         d1 := now();
       k:=1;
       repeat
         SubStr1(s, 10,20,subS1);
         SubStr1(s, 10,20,subS2);     SubStr1(s, 20,5,subS1);
         SubStr1(s, 20,5,subS2);     SubStr1(s, 30,7,subS1);
         SubStr1(s, 30,7,subS2);     SubStr1(s, 50,9,subS1);
         SubStr1(s, 50,9,subS2);     SubStr1(s, 77,11,subS1);
         SubStr1(s, 81,11,subS2);     SubStr1(s, 112,19,subS1);
         SubStr1(s, 54,19,subS2);     SubStr1(s, 211,4,subS1);
         SubStr1(s, 178,37,subS2);     SubStr1(s, 179,19,subS1);
         SubStr1(s, 165,70,subS2);     SubStr1(s, 63,119,subS1);
         SubStr1(s, 16,170,subS2);     SubStr1(s, 13,200,subS1);
         SubStr1(s, 7,220,subS2);     inc(k);
       until k=100000;
       d2 := now();
       caption := Formatdatetime('hh:nn:ss:zzz',d2)+'-'+Formatdatetime('hh:nn:ss:zzz',d1);
       // 该测试结果:经运行 约3.3 /100000*20 组
       //机器配置:cpu:piii 1G 512内存  delphi7
    end;
      

  12.   

    For i:=1 to ACount  do
          dStr[i] := sStr[AFrom+i-1] ;

       Move(sStr[AFrom], dStr[1], ACount);
    慢多了, Move 在操作时是使用 4 字节 Movsd 指令操作的, 不要快得太多哦!还有, SetLength(dStr, ACount); 这句语句执行的效率极低! 还不如:
    //procedure (AStr: String; var ADest: ShortString; AFrom, ACount: Integer);
    Move(AStr[AFrom], ADest[1], ACount);
    ADest[0] := Char(ACount);
    快多了, 重复利用 ADest 局部变量作为交换数据缓冲区, 这样避免不断的分配和释放内存.其实, 我在上面提到的方法已经非常快了, 若还有最快的就是直接定义各个子串常量.
      

  13.   

    拆份字符串的问题我已经解决了,用的是xjlqlqlq(小虫)的方法,加上我自己的一些处理,现在,我想把那些要取的位置也保存下来,但是我不想用类来保存,主要原因是太慢了。我该怎么办呀?