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;