问题1:如何将形如字符串 1-12,35,8-31 转化为 [1..31,35]这样的集合变量?
问题2:如何将 [1..31,35] 这样的集合便利转化为 1-31,35 这样的字符串?

解决方案 »

  1.   

    type
      TSysByteSet = set of Byte;function StringToByteSet(mStr: string): TSysByteSet;
    var
      I, J: Integer;
      T: Integer;
    begin
      Result := [];
    //  mStr := StringReplace(mStr, ',', ',', [rfReplaceAll]); //TODO : 矫正输入的数据~~
    //  mStr := StringReplace(mStr, ' ', '', [rfReplaceAll]);
    //  mStr := StringReplace(mStr, '[', '', [rfReplaceAll]);
    //  mStr := StringReplace(mStr, ']', '', [rfReplaceAll]);
      with TStringList.Create do try
        Delimiter := ',';
        DelimitedText := mStr;
        for I := 0 to Count - 1 do begin
          T := Pos('-', Strings[I]);
          if T > 0 then
            for J := StrToIntDef(Copy(Strings[I], 1, T - 1), 0) to
              StrToIntDef(Copy(Strings[I], T + 1, MaxInt), 0) do
              Include(Result, J)
          else Include(Result, StrToIntDef(Strings[I], 0));
        end;
      finally
        Free;
      end
    end; { StringToByteSet }function ByteSetToString(mSet: TSysByteSet): string;
    var
      I, J, K: Integer;
    begin
      Result := '';
      J := 255;
      K := 255;
      for I := 0 to 255 do
        if I in mSet then begin
          if I <> J + 1 then begin
            Result := Result + ',' + IntToStr(I);
            K := I;
          end;
          J := I;
        end else if (K < J) and (I = J + 1) then
          Result := Result + '-' + IntToStr(J);  if (K < J) and (J = 255) then
        Result := Result + '-' + IntToStr(J);
      Delete(Result, 1, 1);
    end; { ByteSetToString }procedure TForm1.Button1Click(Sender: TObject);
    begin
      Caption := ByteSetToString(StringToByteSet('1-12,35,8-31'));
    end;
      

  2.   

    //前提要说在前头呀~~
    //否则就是浪费大家时间~~uses Math;function StrLeft(const mStr: string; mDelimiter: string): string;
    begin
      Result := Copy(mStr, 1, Pos(mDelimiter, mStr) - 1);
    end; { StrLeft }function StrRight(const mStr: string; mDelimiter: string): string;
    begin
      if Pos(mDelimiter, mStr) > 0 then
        Result := Copy(mStr, Pos(mDelimiter, mStr) + Length(mDelimiter), MaxInt)
      else Result := '';
    end; { StrRight }function TidyLimit(mLimitText: string; mDelimiter: Char = ',';
      mLimitLine: string = '-'): string;
    type
      TLimit = record
        rMin, rMax: Extended;
      end;
      PLimit = ^TLimit;
    var
      I, J: Integer;
      T: Integer;
      P: PLimit;
      vLimit: TLimit;
    begin
      Result := '';
      if mLimitLine = '' then Exit;
      with TStringList.Create do try
        Delimiter := mDelimiter;
        DelimitedText := mLimitText;    ///////Begin 处理字符串
        for I := 0 to Count - 1 do begin
          New(P);
          T := Pos(mLimitLine, Strings[I]);
          if T > 0 then begin
            P^.rMin := StrToFloatDef(StrLeft(Strings[I], mLimitLine), 0);
            P^.rMax := StrToFloatDef(StrRight(Strings[I], mLimitLine), 0);
          end else begin
            P^.rMin := StrToFloatDef(Strings[I], 0);
            P^.rMax := P^.rMin;
          end;
          Objects[I] := TObject(P);
        end;
        ///////End 处理字符串    ///////Begin 合并区域
        for I := Count - 1 downto 0 do begin
          vLimit := PLimit(Objects[I])^;
          for J := I - 1 downto 0 do begin
            P := PLimit(Objects[J]);
            if Max(vLimit.rMin, P^.rMin) <= Min(vLimit.rMax, P^.rMax) then begin //相交
              P^.rMin := Min(vLimit.rMin, P^.rMin);
              P^.rMax := Max(vLimit.rMax, P^.rMax);
              Dispose(PLimit(Objects[I]));
              Delete(I);
              Break;
            end;
          end;
        end;
        ///////End 合并区域    ///////Begin 输出字符、释放资源
        for I := 0 to Count - 1 do begin
          P := PLimit(Objects[I]);
          if P^.rMin = P^.rMax then
            Result := Format('%s,%s', [Result, FloatToStr(P^.rMin)])
          else Result := Format('%s,%s%s%s',
            [Result, FloatToStr(P^.rMin), mLimitLine, FloatToStr(P^.rMax)]);
          Dispose(P);
        end;
        ///////End 输出字符、释放资源
      finally
        Free;
      end;
      Delete(Result, 1, 1);
    end; { TidyLimit }//Example
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      Caption := TidyLimit('1-2,2-3,5,7,8,12-45');
    end;
      

  3.   

    请容我再加几句,这样做,函数就不会在极大、极小值反了的情况下失效了    ///////Begin 处理字符串
        for I := 0 to Count - 1 do begin
          New(P);
          T := Pos(mLimitLine, Strings[I]);
          if T > 0 then begin
            P^.rMin := StrToFloatDef(StrLeft(Strings[I], mLimitLine), 0);
            P^.rMax := StrToFloatDef(StrRight(Strings[I], mLimitLine), 0);
          end else begin
            P^.rMin := StrToFloatDef(Strings[I], 0);
            P^.rMax := P^.rMin;
         > if P^.rMin > P^.rMax then
         > begin
         >   tSwap := P^.rMax;
         >   P^.rMax := P^.rMin;
         >   P^.rMin := tSwap;
         > end;
          end;
          Objects[I] := TObject(P);
        end;
        ///////End 处理字符串  大虾的程序在挂几天吧,让我们这些后学多瞻仰一下。 :)