아브아카의 세상 빼꼼 바라보기

델파이 stringlist Natural Order 정렬하기 본문

컴퓨터/Delphi 코딩

델파이 stringlist Natural Order 정렬하기

아브아카 2015. 8. 5. 17:54

Natural Order가 무엇이냐하면 윈도우 탐색기의 정렬방식이다.

A1 A2 A10 B2 B21 B10 이것을 정렬하면


사전식순이다. Stringlist.Sort로 정렬하는 방법이다.

A1

A10

A2

B10

B2

B21


Natural Order순은 숫자부분을 크기순으로 정렬한다.

A1

A2

A10

B2

B10

B21


구글에 Delphi Natural Order로 검색해보니 C소스를 국내에 번역해놓은 분이 계셨다. 이것을 Stringlist CustomSort에 붙여봤다.


function NaturalOrderCompareString( const A1, A2: string; ACaseSensitive: Boolean ): Integer;
var
  Str1, Str2: PChar;
  Pos1, Pos2: Integer;
  EndPos1, EndPos2: Integer;
begin
  Str1 := PChar(A1);
  Str2 := PChar(A2);

  Pos1 := -1;
  Pos2 := -1;

  while True do
  begin
    Inc( Pos1 );
    Inc( Pos2 );

    if (Str1[Pos1] = #0) and (Str2[Pos2] = #0) then
    begin
      Result := 0;
      Exit;
    end
    else if Str1[Pos1] = #0 then
    begin
      Result := -1;
      Exit;
    end
    else if Str2[Pos2] = #0 then
    begin
      Result := 1;
      Exit;
    end;

    if (Str1[Pos1] >= '0') and (Str1[Pos1] <= '9') and
       (Str2[Pos2] >= '0') and (Str2[Pos2] <= '9') then
    begin
      EndPos1 := Pos1;
      repeat
        Inc(EndPos1);
      until not ((Str1[EndPos1] >= '0') and (Str1[EndPos1] <= '9'));

      EndPos2 := Pos2;
      repeat
        Inc(EndPos2);
      until not ((Str2[EndPos2] >= '0') and (Str2[EndPos2] <= '9'));

      while True do
      begin
        if EndPos1 - Pos1 = EndPos2 - Pos2 then
        begin
          // 이부분이 숫자비교임. StrToInt 한 다음에 빼도 될 것임
          Result := CompareStr( Copy(Str1, Pos1+1, EndPos1 - Pos1),  Copy(Str2, Pos2+1, EndPos1 - Pos1) ) ;

          if Result = 0 then
          begin
            Pos1 := EndPos1 - 1;
            Pos2 := EndPos2 - 1;
            Break;
          end
          else
          begin
            Exit;
          end;
        end
        else if EndPos1 - Pos1 > EndPos2 - Pos2 then
        begin
          if Str1[Pos1] = '0' then
            Inc(Pos1)
          else
          begin
            Result := 1;
            Exit;
          end;
        end
        else
        begin
          if Str2[Pos2] = '0' then
            Inc( Pos2 )
          else
          begin
            Result := -1;
            Exit;
          end;
        end;
      end;
    end
    else
    begin
      if ACaseSensitive then
        Result := CompareStr( Copy(Str1, Pos1, 1), Copy(Str2, Pos2, 1) )
      else
        Result := CompareText( Copy(Str1, Pos1, 1), Copy(Str2, Pos2, 1) );

      if Result <> 0 then
        Exit;
    end;
  end;
end;

function StringListCompareStrings(List: TStringList; Index1, Index2: Integer): Integer;
begin
  Result := NaturalOrderCompareString(List[Index1], List[Index2], True );
end;


procedure TForm1.Button1Click(Sender: TObject);

begin

    Stringlist.CustomSort(StringListCompareStrings);

end;


Natural Order 소스 출처 : http://yypbd.tistory.com/590


'컴퓨터 > Delphi 코딩' 카테고리의 다른 글

Delphi Lite  (0) 2018.04.17
Delphi lisbox drag and drop  (0) 2015.06.17