0 Members and 2 Guests are viewing this topic.
procedure QuickSort(var Field: array of string; Left, Right: integer; SortBy: integer); // Thanks DorkeyDear for your notevar l, r: integer; Pivot, Buffer: string;begin if (Left < Right) then begin l:= Left; r:= Right; Pivot:= GetPiece(Field[(Left + Right) shr 1], #9, SortBy); repeat while (GetPiece(Field[l], #9, SortBy) > Pivot) do begin Inc(l, 1); end; while (GetPiece(Field[r], #9, SortBy) < Pivot) do begin Dec(r, 1); end; if (l <= r) then begin Buffer:= Field[r]; Field[r]:= Field[l]; Field[l]:= Buffer; Inc(l, 1); Dec(r, 1); end; until (l >= r); if (Left < r) then begin QuickSort(Field, Left, r, SortBy); end; if (Right > l) then begin QuickSort(Field, l, Right, SortBy); end; end else begin exit; end;end;
I'm using a combination of both to sort a TStringArray by different variable types. It will be implemented in my upcoming project calling "LogInSystem"
Well, sorry, but, how is it useful?
You can input an array in the procedure, but nothing will come out. It looks as if you think that an 'array of String/Integer' is a pointer, but it's not. I think you will need to make a function out of it, one that will return the sorted array.
The procedure will call itself in the process. I'm not sure if that's possible, actually.. Is it?
Quote from: Markus Quär on July 21, 2008, 02:28:33 pmI'm using a combination of both to sort a TStringArray by different variable types. It will be implemented in my upcoming project calling "LogInSystem" I really wonder what you mean here. AFAIK a TStringArray is not much different as an Array of String... again: Is it?
Besides that it looks like an interesting part of code, also nice you like beer...
Dang man, this is wicked awesome! Definitly usful for charts and tables and stuff. Possibly could be used w/ my Table function to draw tables organized in any way on ppl''s consoles. Good job!
EDIT: using tstringarray instead of array of string slightly slows down the function, which can be bad for larger arrays.
Could you explain the args?procedure QuickSort(var Field: array of string; Left, Right: integer; SortBy: integer);I get Field, but what do Left, Right, and SortBy mean?
Relating to the SortBy value, i suggest having two inputs, a delimiter string, along with the number of delimiter passes (that one getpiece number), but -1 = whole string thoughEDIT: is there a choice for ascending or descending? I suggest having a boolean input for descending if true
// Divide & conquer in order you would like to sort:Pprocedure QuickSort(var Field: array of string; Left, Right, SortBy: integer; Delimiter: string; DescendingOrder: boolean);var l, r: integer; Pivot, Buffer, CompareValueL, CompareValueR: string;begin // Chek whether there is at least more than one elment to sort if (Left < Right) then begin l:= Left; r:= Right; if (SortBy <= 0) then begin CompareValueL:= Field[l]; CompareValueR:= Field[r]; // Pick the Pivot element Pivot:= Field[(Left + Right) shr 1]; end else begin CompareValueL:= GetPiece(Field[l], Delimiter, SortBy); CompareValueR:= GetPiece(Field[l], Delimiter, SortBy); // Pick the Pivot element Pivot:= GetPiece(Field[(Left + Right) shr 1], Delimiter, SortBy); end; repeat if (DescendingOrder = true) then begin // Search an element which is smaller than the piviot while (CompareValueL > Pivot) do begin Inc(l, 1); end; // Search an element which is greater than the pivot while (CompareValueR < Pivot) do begin Dec(r, 1); end; end else begin // Search an element which is greater than the pivot while (CompareValueL < Pivot) do begin Inc(l, 1); end; // Search an element which is smaller than the pivot while (CompareValueR > Pivot) do begin Dec(r, 1); end; end; // Swap the greater element with the smaller one if (l <= r) then begin Buffer:= Field[r]; Field[r]:= Field[l]; Field[l]:= Buffer; Inc(l, 1); Dec(r, 1); end; until (l >= r); if (Left < r) then begin QuickSort(Field, Left, r, SortBy, Delimiter, DescendingOrder); end; if (Right > l) then begin QuickSort(Field, l, Right, SortBy, Delimiter, DescendingOrder); end; end else begin exit; end;end;
Edit: Do you mean that I still have to use GetPiece and adding the exception - 1 = whole string
function ZeroFill(S: string; Peak: integer; IsEnabled: boolean): string;var i, m: integer;begin if (IsEnabled) then begin m:= Peak - length(S); for i:= 1 to m do begin S:= '0' + S; end; end; result:= S;end;function QuickSort(var AOS: array of string; Left, Right: integer; Ival: boolean): integer;var b, e, Pivot: string; i, l, m, r: integer;begin if (Right > Left) then begin for i:= 0 to Right do begin if (length(AOS[i]) > m) then begin m:= length(AOS[i]); end; end; l:= Left; r:= Right; Pivot:= ZeroFill(AOS[Random(Left, Right)], m, Ival); repeat while ((ZeroFill(AOS[l], m, IVal) > Pivot) and (l < Right)) do begin Inc(l, 1); end; while ((ZeroFill(AOS[r], m, IVal) < Pivot) and (r > Left)) do begin Dec(r, 1); end; if (l <= r) then begin b:= AOS[r]; AOS[r]:= AOS[l]; AOS[l]:= b; Inc(l, 1); Dec(r, 1); Inc(Result, 1); end; until (l >= r); if (Left < r) then begin QuickSort(AOS, Left, r, Ival); end; if (Right > l) then begin QuickSort(AOS, l, Right, Ival); end; end else begin exit; end;end;
for i:= 0 to Right do begin if (length(AOS[i]) > m) then begin m:= length(AOS[i]); end; end;
function QuickSort4(var AOS: TStringList; const Left, Right: integer; Ival: boolean; Separator:String; SortBy, m: integer): integer;var b, Pivot: string; l, r: integer;begin if Right > Left then begin l := Left; r := Right; Pivot := ZeroFill(GetPieceSC3(AOS[Random(Left, Right)], Separator, SortBy), m, Ival); repeat while (ZeroFill(GetPieceSC3(AOS[l], Separator, SortBy), m, IVal) > Pivot) and (l < Right) do Inc(l, 1); while (ZeroFill(GetPieceSC3(AOS[r], Separator, SortBy), m, IVal) < Pivot) and (r > Left) do Dec(r, 1); if l <= r then begin b := AOS[r]; AOS[r] := AOS[l]; AOS[l] := b; Inc(l, 1); Dec(r, 1); Inc(Result, 1); end; until l >= r; if Left < r then QuickSort4(AOS, Left, r, Ival, Separator, SortBy, m); if Right > l then QuickSort4(AOS, l, Right, Ival, Separator, SortBy, m); end else exit;end;
function GetPieceSC3(Str, Reg: string; Number: Word): string;var Res: TStringList;begin try Res := File.CreateStringList; SplitRegExpr(QuoteRegExprMetaChars(Reg), Str, Res); Result := Res.Strings[Number]; except finally Res.Free; end;end;
function CaseTbl(Z: Int64): Int64;begin case Z of 0..9: Result := 1; 10..99 : Result := 2; 100..999: Result := 3; 1000..9999: Result := 4; 10000..99999: Result := 5; 100000..999999: Result := 6; 1000000..9999999: Result := 7; 10000000..99999999: Result := 8; 100000000..999999999: Result := 9; 1000000000..9999999999: Result := 10; 10000000000..99999999999: Result := 11; 100000000000..999999999999: Result := 12; 1000000000000..9999999999999: Result := 13; 10000000000000..99999999999999: Result := 14; 100000000000000..999999999999999: Result := 15; 1000000000000000..9999999999999999: Result := 16; 10000000000000000..99999999999999999: Result := 17; 100000000000000000..999999999999999999: Result := 18; 1000000000000000000..9223372036854775807: Result := 19; end;end;
function ZeroRemover(s:string):string;var i, TempLen: integer;begin TempLen := Length(s); for i := 1 to TempLen do begin if s[i] = '0' then continue else begin Result := Copy(s,i,TempLen); exit; end; end;end;
function ScriptCoreQuickSortAllIn(List: TStringList; Separator: string; SortingDirection:boolean): TStringList;var i,b: int64; TempLen, NumCounterMax: byte; ForTest: TStringList; TempString: String;begin if List.Count > 0 then begin ForTest := File.CreateStringList(); for i := 0 to List.Count-1 do begin ForTest.Append(GetPieceSC3(List[i],Separator,0)); TempLen := Length(ForTest[i]); if TempLen > NumCounterMax then NumCounterMax := TempLen; end; for i := 0 to List.Count-1 do begin TempString := ForTest[i]; for b:= 1 to NumCounterMax - length(ForTest[i]) do TempString := '0' + TempString; List[i] := TempString+Copy(List[i],Length(ForTest[i]+Separator),Length(List[i])); end; ForTest.Free; With List do try BeginUpdate; List.Sort; if SortingDirection then begin for i := 0 to List.Count-1 do begin TempLen := Length(List[i]); for b := 1 to TempLen do begin TempString := List[i]; if TempString[b] = '0' then continue else begin List[i] := Copy(TempString,b,TempLen); break; end; end; end; end else begin for i := 0 to List.Count-1 do begin TempLen := Length(List[i]); for b := 1 to TempLen do begin TempString := List[i]; if TempString[b] = '0' then continue else begin List[i] := Copy(TempString,b,TempLen); break; end; end; List.Move(i, 0); end; end; Result := List; Finally EndUpdate end; end;end;
function GetPieceSC3(Str, Reg: string; Number: Word): string;var Res: TStringList;begin try Res := File.CreateStringList; SplitRegExpr(QuoteRegExprMetaChars(Reg), Str, Res); Result := Res.Strings[Number]; except Result := ''; finally Res.Free; end;end;function ZeroFill(S: string; Peak: integer; IsEnabled: boolean): string;var i, m: integer;begin if IsEnabled then begin m := Peak - length(S); for i:= 1 to m do S := '0' + S; end; result := S;end;function ZeroRemover(s:string):string;var i, TempLen: integer;begin TempLen := Length(s); for i := 1 to TempLen do begin if s[i] = '0' then continue else begin Result := Copy(s,i,TempLen); exit; end; end;end;function ScriptCoreQuickSort(List: TStringList; Separator: string; SortingDirection:boolean): TStringList;var i: int64; TempLen, NumCounterMax: byte; ForTest: TStringList;begin if List.Count > 0 then begin ForTest := File.CreateStringList(); for i := 0 to List.Count-1 do begin ForTest.Append(GetPieceSC3(List[i],Separator,0)); TempLen := Length(ForTest[i]); if TempLen > NumCounterMax then NumCounterMax := TempLen; end; for i := 0 to List.Count-1 do List[i] := ZeroFill(ForTest[i],NumCounterMax,true)+Copy(List[i],Length(ForTest[i]+Separator),Length(List[i])); ForTest.Free; With List do try BeginUpdate; List.Sort; if SortingDirection then for i := 0 to List.Count-1 do List[i] := ZeroRemover(List[i]) else begin for i := 0 to List.Count-1 do begin List[i] := ZeroRemover(List[i]); List.Move(i, 0); end; end; Result:=List; Finally EndUpdate end; end;end;
TimeStart := Now(); for TempIndexID := 1 to 5000 do begin NUMA.Append('123'+#9+'TESTOWYGRACZ'+#9+'dasdasd 123123'); NUMA.Append('2'+#9+'0012312412'+#9+'asdaq1a sd2123'); NUMA.Append('8'+#9+'dasauto'+#9+'sadasd asdasd'); NUMA.Append('1'+#9+'00manek'+#9+'ssss 555'); NUMA.Append('9'+#9+'truo'+#9+'gggg 333'); NUMA.Append('13'+#9+'misterer'+#9+'asdasdas 677'); NUMA.Append('99'+#9+'0000asdsa'+#9+'666666 1123231'); NUMA.Append('77'+#9+'2nb3epd9fh12'+#9+'1213 44123'); ScriptCoreQuickSortAllIn(NUMA, #9, false); Numa.Clear; end; WriteLn('[new] Sorting batle '+FormatDateTime('ss,zzz', Now()-TimeStart)+'s'); TimeStart := Now(); for TempIndexID := 1 to 5000 do begin NUMA.Append('123'+#9+'TESTOWYGRACZ'+#9+'dasdasd 123123'); NUMA.Append('2'+#9+'0012312412'+#9+'asdaq1a sd2123'); NUMA.Append('8'+#9+'dasauto'+#9+'sadasd asdasd'); NUMA.Append('1'+#9+'00manek'+#9+'ssss 555'); NUMA.Append('9'+#9+'truo'+#9+'gggg 333'); NUMA.Append('13'+#9+'misterer'+#9+'asdasdas 677'); NUMA.Append('99'+#9+'0000asdsa'+#9+'666666 1123231'); NUMA.Append('77'+#9+'2nb3epd9fh12'+#9+'1213 44123'); QuickSort4(NUMA, 0, NUMA.Count-1, true, #9, 0, 3); Numa.Clear; end; WriteLn('[old] Sorting batle '+FormatDateTime('ss,zzz', Now()-TimeStart)+'s');