Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[14332] Re: 숫자 포함된 문자열 정렬에 대해서
오랑캐꽃 [oranke] 2077 읽음    2012-06-29 12:52
아~~ 저 이런 문제 너무 좋아해요. (... 왜그런지는 잘 모르겠...)

여러가지 방법이 있겠지만, 주어진 문자열에서 숫자값만 떼어내 새로운 문자열을 만들어 비교하는
단순 무식한 방법을 하나 제시해 봅니다.
즉 "AAA_1_1_1.txt " 을 "00001.00001.00003" 으로 바꿔서 비교하자는 이야기.

먼저 숫자를 포함한 문자열에서 숫자값만 떼어내 비교용 문자열을 만드는 함수를 작성합니다.

function MakeCompareStr(const aString: String): String;
const
  FORMAT_STR = '%.5d';
var
  i: Integer;
  tmpStr: String;
begin
  tmpStr := '';
  Result := '';

  for i:= 1 to Length(aString) do
  begin
    if aString[i] in ['0' .. '9'] then
      tmpStr := tmpStr + aString[i]
    else
    if Length(tmpStr) > 0 then
    begin
      Result := Result + '.' + Format(FORMAT_STR, [StrToIntDef(tmpStr, 0)]);
      tmpStr := '';
    end;
  end;

  if Length(tmpStr) > 0 then
    Result := Result + '.' + Format(FORMAT_STR, [StrToIntDef(tmpStr, 0)]);
end;



리스트박스의 "Items: TStrings" 를 정렬하기 위한 퀵소트 함수를 하나 만들어줍니다.

type
  TStringsSortCompare = function(Strings: TStrings; Index1, Index2: Integer): Integer;

procedure QuickSortStrings(Strings: TStrings; L, R: Integer; Compare: TStringsSortCompare);
var
  I, J, P: Integer;
begin
  repeat
    I := L;
    J := R;
    P := (L + R) shr 1;
    repeat
      while Compare(Strings, I, P) < 0 do Inc(I);
      while Compare(Strings, J, P) > 0 do Dec(J);
      if I <= J then
      begin
        Strings.Exchange(I, J);
        if P = I then
          P := J
        else if P = J then
          P := I;
        Inc(I);
        Dec(J);
      end;
    until I > J;
    if L < J then QuickSortStrings(Strings, L, J, Compare);
    L := I;
  until I >= R;
end;



정렬함수는 이렇게...

function CompareStrAsNum(Strings: TStrings; Index1, Index2: Integer): Integer;
begin
  Result :=
    CompareStr(
      MakeCompareStr(Strings[Index1]),
      MakeCompareStr(Strings[Index2])
    );
end;



리스트에 내용을 넣고 다음과 같이 정렬을 때려 봅니다.

procedure TForm1.Button3Click(Sender: TObject);
begin
  QuickSortStrings(ListBox1.Items, 0, ListBox1.Items.Count-1, CompareStrAsNum);
end;



결과는 다음과 같습니다.

AAA_1_1_1.txt
AAA_1_1_2.txt
AAA_1_1_3.txt
AAA_1_1_10.txt
AAA_1_1_11.txt
AAA_1_1_20.txt



설명을 위해 재미로 작성한 코드니 효율에 대한 딴지는 걸지 말아주세요.
(개념인들의 민원에 시달리다보니 코드 적고나면 걱정부터 앞서는...)



잠자리 님이 쓰신 글 :
: AAA_1_1_3.txt
: AAA_1_1_1.txt
: AAA_1_1_2.txt
: AAA_1_1_10.txt
: AAA_1_1_11.txt
: AAA_1_1_20.txt
:
: 위 내용을 리스트 박스에 넣고 정렬하면 일반적으로 아래와 같이 정렬 됩니다.
:
: AAA_1_1_1.txt
: AAA_1_1_10.txt
: AAA_1_1_11.txt
: AAA_1_1_2.txt
: AAA_1_1_20.txt
: AAA_1_1_3.txt
:
: 근데 이걸...아래와 같이 정렬할 수는 없는지요?
:
: AAA_1_1_1.txt
: AAA_1_1_2.txt
: AAA_1_1_3.txt
: AAA_1_1_10.txt
: AAA_1_1_11.txt
: AAA_1_1_20.txt
:
: 고수님들의 가르침 부탁합니다.

+ -

관련 글 리스트
14331 숫자 포함된 문자열 정렬에 대해서 잠자리 1885 2012/06/29
14332     Re: 숫자 포함된 문자열 정렬에 대해서 오랑캐꽃 2077 2012/06/29
14334         Re:Re: 숫자 포함된 문자열 정렬에 대해서 장성호 2709 2012/06/29
14333         Re:Re: 숫자 포함된 문자열 정렬에 대해서 잠자리 2072 2012/06/29
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.