인덱스로 배열 정렬하기: C++로 신비를 해제하다

배열 정렬은 프로그래밍에서 기본적인 작업이지만, 정렬된 값 대신 정렬된 값의 인덱스만 필요한 경우는 어떻게 해야 할까요? 이러한 일반적인 문제는 많은 개발자들, 특히 C 또는 C++를 사용하는 개발자들의 관심을 끌었습니다. 이 포스트에서는 값으로 배열을 정렬하고 정렬된 순서의 요소 인덱스를 반환하는 방법을 설명하겠습니다.

도전 과제

정수 배열이 있고, 이 배열을 오름차순으로 정렬하는 것이 목표라고 가정해보겠습니다. 하지만 정렬된 숫자 자체를 반환하는 대신, 이러한 정렬된 숫자의 원래 인덱스를 나타내는 배열을 원합니다. 예를 들어, 입력 배열이 다음과 같다고 가정해봅시다:

입력:  1, 3, 4, 9, 6

출력은 정렬된 값의 인덱스를 반영해야 합니다:

출력: 1, 2, 3, 5, 4

정렬의 트위스트

당신은 아마도 쿼리에서 언급한 셸 정렬 절차와 같은 정렬 알고리즘을 사용하고 있을 것입니다. 하지만 특정 프로그래밍 구현은 포인터 작업을 수행할 때 오류를 초래할 수 있습니다. 이 포스트의 목표는 C/C++에서 배열을 다루는 방법과 요구 사항을 충족하는 정렬 함수를 만드는 방법을 명확히 하는 것입니다.

1단계: 포인터 배열 만들기

위치 정보를 잃지 않으면서 정렬을 용이하게 하기 위해, 원래 배열의 요소를 가리키는 포인터 배열을 만들 수 있습니다. 이렇게 하면 포인터를 정렬할 때 원래 배열 값도 간접적으로 정렬되며, 인덱스 맵을 유지할 수 있습니다. 방법은 다음과 같습니다:

int* intArray; // 이 변수는 정수 값으로 초기화됩니다.
int arrayLen;  // 정수 배열의 길이.

int** pintArray = new int*[arrayLen]; // 포인터 배열 생성.
for(int i = 0; i < arrayLen; ++i)
{
    pintArray[i] = &intArray[i]; // 각각의 요소를 가리킵니다.
}

2단계: 포인터 배열 정렬하기

포인터가 준비되면, 가리키는 값에 따라 포인터를 정렬하기 위해 어떤 정렬 알고리즘(예: 셸 정렬)을 적용할 수 있습니다. 아래는 간단한 예시입니다:

SortIntPointers(pintArray, arrayLen); // 값에 따라 포인터 배열을 정렬합니다.

3단계: 정렬된 인덱스 할당하기

포인터를 정렬한 후, 이를 순회하면서 원래 포인터 배열에 해당 정렬된 위치를 할당할 수 있습니다. 이렇게 하면 적절한 인덱스를 얻을 수 있습니다.

for(int i = 0; i < arrayLen; ++i)
{
    *pintArray[i] = i; // 정렬된 인덱스 위치를 할당합니다.
}

전체 구현 예시

위에서 설명한 단계를 따라 전체 예제를 작성해 보겠습니다:

void SortIntPointers(int** pArray, int ArrayLength) {
    int flag = 1;    
    int* temp;    
    
    for (int i = 1; (i <= ArrayLength) && flag; i++)
    {
        flag = 0;
        for (int j = 0; j < ArrayLength - 1; j++)
        {
            if (*pArray[j + 1] < *pArray[j]) // 오름차순으로 변경
            { 
                temp = pArray[j]; // 요소를 교환합니다.
                pArray[j] = pArray[j + 1];
                pArray[j + 1] = temp;
                flag = 1; // 교환이 발생했습니다.
            }
        }
    }
}

// 이전에 설명한 대로 포인터를 초기화하고 정렬합니다.

결론

원래 위치를 잃지 않고 인덱스에 따라 배열을 정렬하는 것은 C/C++에서 특히 포인터와 관련하여 까다로울 수 있습니다. 포인터 배열을 생성하고 이를 정렬함으로써 이러한 문제를 효과적으로 관리할 수 있습니다. 오류 처리를 구현하고 엣지 케이스를 고려하여 더 견고한 코드를 작성하는 것을 잊지 마세요. 즐거운 코딩 되세요!