インデックスで配列をソートする: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++のポインタを扱っているときには。ポインタの配列を作成し、それをソートすることで、この課題を効果的に管理できます。エラーハンドリングを実装し、堅牢なコードのためにエッジケースを考慮することを忘れないでください。コーディングを楽しんでください!