아~~ 저 이런 문제 너무 좋아해요. (... 왜그런지는 잘 모르겠...)
여러가지 방법이 있겠지만, 주어진 문자열에서 숫자값만 떼어내 새로운 문자열을 만들어 비교하는
단순 무식한 방법을 하나 제시해 봅니다.
즉 "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
:
: 고수님들의 가르침 부탁합니다.