1. int 배열 정렬
int numArr[10]{ 10, 332, 30, 4, 55, 63, 77, 28, 49, 810 };
qsort (numArr, sizeof(numArr) / sizeof(int), sizeof(int), SortAscending);
int SortAscending(const void* n1, const void* n2)
{
if (*(int*)n1 > *(int*)n2) return 1;
else if(*(int*)n1 < *(int*)n2) return -1;
else return 0;
}
int SortDescending(const void* n1, const void* n2)
{
if (*(int*)n1 > *(int*)n2) return -1;
else if (*(int*)n1 < *(int*)n2) return 1;
else return 0;
}
오름차순 정렬 결과입니다. 내림차순을 적용하려면 qsort를 호출할때 SortDescending을 사용하면 됩니다.
qsort에 사용된 sort함수가 특별한건 아니고 반환하는 값이 음수일 경우 첫번째 요소가 두번째 요소보다 먼저 위치해야된다는 의미이고 양수면 그 반대의 의미입니다. 그리고 0이면 같다는 것이겠죠.
2. CStringArray 정렬
CStringArray list;
list.Add(_T("123"));
list.Add(_T("20"));
list.Add(_T("45"));
list.Add(_T("1005"));
list.Add(_T("205"));
qsort(list.GetData(), list.GetSize(), sizeof(CString), SortAscending);
int SortAscending(const void* p1, const void* p2)
{
CString* s1 = (CString*)p1;
CString* s2 = (CString*)p2;
return _tcscmp(s1->GetBuffer(0), s2->GetBuffer(0));
}
int SortDescending(const void* p1, const void* p2)
{
CString* s1 = (CString*)p1;
CString* s2 = (CString*)p2;
return _tcscmp(s1->GetBuffer(0), s2->GetBuffer(0)) * -1;
}
오름차순 정렬 결과입니다. 하지만 원하는 결과값은 아닌것 같죠..?
이런 결과가 나온 이유를 이해하려면 문자열 비교 함수인 _tcscmp() 함수의 특성 대해 알아야됩니다.
_tcscmp() 함수는 두 문자열을 비교해서 같으면 0, 다르면 값에 따라 1 또는 -1을 반환하는데 앞에서부터 한자리씩 문자의 아스키코드값을 비교하면서 어떤 문자가 큰지 판단합니다.
1005와 123을 숫자로 비교하면 1005가 크지만 코드 값으로 비교하면 첫번째 1은 똑같고 두번째는 123의 2가 더 크니 123이 더 크다고 판단합니다. 그리고 20과 205는 끝에 널문자(\0)가 있고 이 문자는 아스키 코드상 0이라 가장 작은 값이기 때문에 20이 205보다 작은 것으로 판단합니다. 즉 앞부분이 같다면 짧은 문자열을 더 작다고 판단하게 되는것이죠.
하지만 문자열에 숫자만 있으란 법이 없기때문에 정답은 없습니다.
데이터가 숫자 위주면 _ttoi() 함수를 이용해서 CString을 int로 변환해서 위에 int 정렬하듯이 하면 될것이고
문자열 길이라든지 원하는 정렬 방법이 있다면 _tcscmp를 사용하지 않고 return값에 따라 정렬이 된다는 것을 이해하고 구현하면 될 것 같습니다.
3. CPtrArray 정렬
class CMyItem
{
public:
CMyItem() {}
virtual ~CMyItem() {}
int m_nId;
CString m_sName;
};
CPtrArray CItemArray;
for (int i = 0; i < 5; i++)
{
CMyItem* newItem = new CMyItem;
newItem->m_nId = i + 1;
newItem->m_sName.Format(_T("이름 %d"), i + 1);
CItemArray.Add(newItem);
}
qsort(CItemArray.GetData(), CItemArray.GetSize(), sizeof(CMyItem*), SortDescending);
for (int i = 0; i < CItemArray.GetCount(); i++)
{
CMyItem* myItem = (CMyItem*)CItemArray.GetAt(i);
delete myItem;
}
int SortAscending(const void* p1, const void* p2)
{
CMyItem** item1 = (CMyItem**)p1;
CMyItem** item2 = (CMyItem**)p2;
if ((*item1)->m_nId > (*item2)->m_nId) return 1;
else if((*item1)->m_nId < (*item2)->m_nId) return -1;
else return 0;
}
int SortDescending(const void* p1, const void* p2)
{
CMyItem** item1 = (CMyItem**)p1;
CMyItem** item2 = (CMyItem**)p2;
if ((*item1)->m_nId > (*item2)->m_nId) return - 1;
else if((*item1)->m_nId < (*item2)->m_nId) return 1;
else return 0;
}
CPtrArray는 더블 포인터로 클래스 받아온 다음에 마찬가지로 원하는 정렬 조건으로 정렬하면 되겠습니다.
'C++, MFC' 카테고리의 다른 글
[C++/MFC] vcpkg를 사용해서 프로젝트에 라이브러리 세팅하는 방법 (0) | 2022.11.30 |
---|---|
[MFC] _WIN32_WINNT not defined. Defaulting to _WIN32_WINNT_MAXVER (see WinSDKVer.h) 문제 해결 (0) | 2022.10.20 |
[MFC] 프로그램 내부에서 다른 프로그램(exe, msi) 설치하는 방법 / exe, msi 설치 옵션 (1) | 2022.09.29 |
[MFC] 프로세스간 통신 (Inter Process Communication, IPC) 방법 설명 (0) | 2022.09.27 |
[C++/MFC] 인코딩, 유니코드 구분해서 CFile로 txt파일 읽는 방법 (0) | 2022.09.22 |
댓글