看来 没有 多少人 喜欢 讨论 算法这个 是代码我的机器千万次 比较一秒以内配置差点的 可能 要 1.5秒 左右unit filter;interfaceconst FilterSeparator = '-'; FilterRangeChar = '~'; FilterMaxColCount = 255; // hfghfghfg 2009-11-07type PColRec = ^TColRec; TColRec = record P: PChar; Length: Integer; end; TNumRec = record Col: array[0..FilterMaxColCount - 1] of TColRec; Colcount: Integer; end; TFilter_Base = class private FFilter: string; FIsCompiled: boolean; procedure SetFilter(const Value: string); protected procedure clearCompiled; virtual; function CompileFilter(v: string): boolean; virtual; function docheck(v: pchar; len: integer): boolean; virtual; public destructor Destroy; override; property Filter: string read FFilter write SetFilter; property IsCompiled: Boolean read FIsCompiled; function check(v: pchar; len: integer): boolean; end; TFilter_Range = class(TFilter_Base) private min_v: string; max_v: string; min_Num: TNumRec; max_Num: TNumRec; protected procedure clearCompiled; override; function CompileFilter(v: string): boolean; override; function docheck(v: pchar; len: integer): boolean; override; end;procedure Num2NumRec(v: pchar; len: integer; var Num: TNumRec);implementationuses StrUtils, SysUtils, math;procedure Num2NumRec(v: pchar; len: integer; var Num: TNumRec);var p: pchar; i: integer; PCol: PColRec;begin Num.Colcount := 0; if len <= 0 then exit; p := v; PCol := @(Num.Col[0]); PCol.Length := 0; for i := 1 to len do begin if p^ = FilterSeparator then begin inc(PCol); PCol^.Length := 0; end else begin if PCol^.Length = 0 then begin PCol^.P := p; inc(Num.Colcount); end; inc(PCol^.Length); end; inc(p); end;end;function ComparePchar(p_1, p_2: pchar; len: Integer): integer;var p1, p2: pchar; i: integer;begin Result := 0; p1 := p_1; p2 := p_2; for i := 1 to len do begin if p1^ > p2^ then begin Result := 1; // 大于 exit; end else if p1^ < p2^ then begin Result := -1; // 小于 exit; end; inc(p1); inc(p2); end;end;function CompareNumRec(var Num1, Num2: TNumRec): integer;var i, c: integer; PCol1: PColRec; PCol2: PColRec;begin Result := 0; c := min(Num1.Colcount, Num2.Colcount); PCol1 := @(Num1.Col[0]); PCol2 := @(Num2.Col[0]); for i := 1 to c do begin if PCol1^.Length > PCol2.Length then begin Result := 1; // 大于 end else if PCol1^.Length < PCol2.Length then begin Result := -1; // 小于 end else begin Result := ComparePchar(PCol1.P, PCol2.P, PCol1^.Length); if Result <> 0 then exit; end; inc(PCol1); inc(PCol2); end;end;{ filter }function TFilter_Base.check(v: pchar; len: integer): boolean;begin Result := docheck(v, len);end;procedure TFilter_Base.clearCompiled;begin//end;function TFilter_Base.CompileFilter(v: string): boolean;begin Result := false; try except end; Result := true;end;destructor TFilter_Base.Destroy;begin clearCompiled; inherited;end;function TFilter_Base.docheck(v: pchar; len: integer): boolean;begin Result := false;end;procedure TFilter_Base.SetFilter(const Value: string);begin clearCompiled; FIsCompiled := false; FFilter := Value; FIsCompiled := CompileFilter(FFilter);end;{ TFilter_Range }procedure TFilter_Range.clearCompiled;begin//end;function TFilter_Range.CompileFilter(v: string): boolean;var i: integer; function checkstr(v: string): string; begin Result := UpperCase(Trim(v)) end;begin Result := false; i := Pos(FilterRangeChar, v); if i > 1 then begin try min_v := checkstr(copy(v, 1, i - 1)); Num2NumRec(@min_v[1], length(min_v), min_Num); max_v := checkstr(copy(v, i + 1, maxint)); Num2NumRec(@max_v[1], length(max_v), max_Num); except end; end;end;function TFilter_Range.docheck(v: pchar; len: integer): boolean;var Num: TNumRec;begin Num2NumRec(v, len, Num); if CompareNumRec(Num, min_Num) < 0 then begin result := False; exit; end; if CompareNumRec(Num, max_Num) > 0 then begin result := False; exit; end; Result := true;end;end.