function Cfgs(s1: string; s2: string): INTEGER; var i, j, HMS: integer; begin s1 := trim(s1); HMS := LENGTH(S1) + 1; HMS := TRUNC(HMS / 3); s2 := trim(s2); j := 0; for i := 1 to HMS do if POS(COPY(S1, (I - 1) * 3 + 1, 2), s2) > 0 then j := j + 1; Cfgs := J; end;
//先用一组数据测试 procedure DataTotal(const AStr: string; const ACondStrings, ARsStrings: TStrings); var sList,sRsList: TStringList; i,j,iC: Integer; sName,sValue: string; begin sList := nil; sRsList := nil; try sRsList := TStringList.Create; sRsList.Sorted := True; sList := TStringList.Create; sList.DelimitedText := AStr; ARsStrings.Clear; for i:=0 to ACondStrings.Count-1 do begin iC := 0; for j:=0 to sList.Count-1 do if Pos(sList[j],ACondStrings[i])>0 then Inc(iC);
sName := IntToStr(iC); if ARsStrings.IndexOfName(sName)=-1 then ARsStrings.Add(sName+'=1') else begin sValue := ARsStrings.Values[sName]; ARsStrings.Values[sName] := IntToStr(StrToInt(sValue)+1); end; end; for j:=0 to sList.Count do begin sName := IntToStr(j); if ARsStrings.IndexOfName(sName)=-1 then ARsStrings.Add(sName+'=0'); end; //排序 sRsList.Clear; sRsList.Assign(ARsStrings); ARsStrings.Clear; ARsStrings.Assign(sRsList); finally sRsList.Free; sList.Free; end; end;
完犊子了,才疏学浅了,没研究明白newbuyer的 ========== 假设一个数组 yALL: array[0..YourMaxValue] of Byte/Word;
FillChar(yALL, sizeof(yALL), 0); for each c:Byte in InputData do Inc(yALL[c]);
for each c:Byte in [1,5,15,19,26,29] do Writeln('Count of '+c+' is ', yALL[c]); ========== 怎么鼓捣都是Pos更快一点……
----------------------------------------------
z@S7
procedure TForm4.SpeedButton1Click(Sender: TObject); var bs: set of byte; i, k: Integer; j: byte; d1: TStopwatch; b: Boolean; begin bs := []; for I := 1 to 10 do begin bs := bs + [i]; end;
b := false;
d1 := TStopwatch.StartNew; for I := 1 to 5000 * 10 do begin j := i mod 100;
for k := 1 to 2000 do begin if j in bs then begin b := true; end; end; end;
type TMyDictPair = record Key: string; Value: integer; end;
TMyArrDictPairs = array of TMyDictPair;
var MyTextWithValues : string; MyTextWithConditions: string;
procedure TViewMyArrDictForm.BtnVerifyConditionsClick(Sender: TObject); var MyArrDictPairs : TMyArrDictPairs; MyDictPair : TMyDictPair; MyDictText : TArray<string>; // array of string; MyDictConditions: TArray<string>; // array of string; LIndexFound : integer; MyGetTicks : UInt64; // **********// function FindMyKeyOnDictPairs(const AArrDictPairs: TMyArrDictPairs; const AKey: string): integer; begin result := -1; // for var i: integer := 0 to high(AArrDictPairs) do if (AArrDictPairs[i].Key = AKey) then exit(i); end;
function FindMyKeyOnText(const AArrText: TArray<string> { array of string }; const AKey: string; const ALastPos: integer): integer; var LIndex: integer; begin result := -1; // for var i: integer := 0 to high(AArrText) do if (ALastPos < i) and (AArrText[i] = AKey) then begin result := i; LIndex := FindMyKeyOnDictPairs(MyArrDictPairs, AKey); MyArrDictPairs[LIndex].Value := MyArrDictPairs[LIndex].Value + 1; end; end;
procedure DontRepeatConditions; function MyFuncDontDuplicates(const ArrValor: TArray<string>; const AVal: string): integer; begin result := -1; // for var i: integer := 0 to high(ArrValor) do if ((ArrValor[i]) = (AVal)) then exit(i); end;
var ArrTmp : TArray<string>; BeforeItem: string; LIndex : integer; begin LIndex := -1; // // ArrTmp := MyDictConditions; ... cause "memory pointer sharing "!!! // for var MyItem in MyDictConditions do // better this way!!! ArrTmp := ArrTmp + [MyItem]; // TArray.Sort<string>(MyDictConditions); // BeforeItem := ''; // for var MyItem in MyDictConditions do begin if (MyItem = BeforeItem) then begin LIndex := MyFuncDontDuplicates(ArrTmp, MyItem); // if LIndex > -1 then Delete(ArrTmp, LIndex, 1); end; // BeforeItem := MyItem; end; // if Length(MyDictConditions) <> Length(ArrTmp) then MyDictConditions := ArrTmp; end;
// **********// begin // // MyDictText := ['10', '53', '34', '01', '94', '86', '42', '71', '01', '76', '84', '100', '2010', '01', '91']; // MyDictConditions := ['01', '34', '45', '91', '84', '103', '33', '05', '9', '26']; // // MyDictText := '10 53 34 01 94 86 42 71 01 76 84 100 2010 01 91 33 40 82 10 10 33 21 14 9820 1201'.Split([' ']); // creating a "TArray<string>" // MyDictConditions := '01 34 45 91 84 103 33 05 9 26 01 10'.Split([' ']); // MyDictText := MyTextWithValues.Split([' '], TStringSplitOptions.ExcludeEmpty); // creating a "TArray<string>" MyDictConditions := MyTextWithConditions.Split([' '], TStringSplitOptions.ExcludeEmpty); // DontRepeatConditions; // unique value in conditions! // Memo1.Text := 'my list of values:'; Memo1.Lines.Add(''.Join(',', MyDictText)); Memo1.Lines.Add(slinebreak + 'My list of conditions:'); Memo1.Lines.Add(''.Join(',', MyDictConditions)); Memo1.Lines.Add('**********'); // // ---------- Preparing... ---------- // for var M1 in MyDictText do begin MyDictPair.Key := M1; MyDictPair.Value := 0; // if (FindMyKeyOnDictPairs(MyArrDictPairs, M1) = -1) then MyArrDictPairs := MyArrDictPairs + [MyDictPair]; end; // Memo1.Lines.Add(slinebreak + '********** Dict prepared **********'); // Memo1.Lines.Add('Total values: ' + Length(MyDictText).ToString); Memo1.Lines.Add('Total conditions: ' + Length(MyDictConditions).ToString); // { Memo1.Lines.BeginUpdate; try for var M2 in MyArrDictPairs do Memo1.Lines.Add(M2.Key + ', ' + M2.Value.ToString); finally Memo1.Lines.EndUpdate; end; } // MyGetTicks := GetTickCount64; // ---------- searching... ----------// LIndexFound := -2; // for var M3 in MyDictConditions do begin while (LIndexFound <> -1) do LIndexFound := FindMyKeyOnText(MyDictText, M3, LIndexFound); // LIndexFound := -2; end; // Memo1.Lines.Add('======== Search Time: ' + (GetTickCount64 - MyGetTicks).ToString + 'ms ========'); // Memo1.Lines.BeginUpdate; try for var M2 in MyArrDictPairs do Memo1.Lines.Add(M2.Key + ', ' + M2.Value.ToString); finally Memo1.Lines.EndUpdate; end; end;
procedure TViewMyArrDictForm.BtnCreateATextToVerifyClick(Sender: TObject); var MyGetTicks: UInt64; begin MyTextWithValues := ''; MyTextWithConditions := ''; // Memo1.Lines.Add(slinebreak + '---------- VALUE: ----------'); // MyGetTicks := GetTickCount64; // for var i: integer := 1 to 20000 do MyTextWithValues := Format(MyTextWithValues + '%d ', [random(1000) + 1]); // MyTextWithValues := MyTextWithValues.Trim; // Memo1.Text := MyTextWithValues; Memo1.Lines.Add(slinebreak + '======== Time: ' + (GetTickCount64 - MyGetTicks).ToString + 'ms ========'); // Memo1.Lines.Add(slinebreak + '---------- CONDITIONS: ----------'); // for var i: integer := 1 to 100 do MyTextWithConditions := Format(MyTextWithConditions + '%d ', [random(1000) + 1]); // MyTextWithConditions := MyTextWithConditions.Trim; // Memo1.Lines.Add(MyTextWithConditions); end;
initialization
ReportMemoryLeaksOnShutdown := True; randomize;
finalization
end.
此帖子包含附件: 大小:80.9K
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
using "SORTED" lists, you can (maybe) win more time on searches...! >:)
dividing your "big list of values" you can works with pieces of block, then, you time can be more usable, I think!
20.000 / 99 = 16ms 100.000 / 491 = 375ms
5 x 16ms = 80ms! = 100.000 values
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3