私はこれをさまざまな状況で何度も行ってきました。配列をソートするのではなく、ソートされたインデックスを持つ新しい配列を作成するだけです。
たとえば、長さ n の配列 (ベクトル) evals と 2d nxn 配列 evects があるとします。値 [0, n-1] を含む新しい配列インデックスを作成します。
次に、evals[i] として evals にアクセスするのではなく、evals[index[i]] としてアクセスし、evects[i][j] の代わりに、evects[index[i]][j] としてアクセスします。
ここで、evals 配列ではなくインデックス配列をソートするソート ルーチンを記述します。したがって、インデックスが {0, 1, 2, ... , n-1} のように見えるのではなく、インデックス配列の値が昇順になります。 evals 配列の値の。
したがって、並べ替えた後、これを行うと:
for (int i=0;i<n;++i)
{
cout << evals[index[i]] << endl;
}
評価のソートされたリストが得られます。
このようにして、実際にメモリを移動することなく、その evals 配列に関連付けられているものを並べ替えることができます。これは n が大きくなった場合に重要です。これは、evects 行列の列を移動したくない場合に重要です。
基本的に、i 番目に小さい eval は index[i] に配置され、index[i] 番目のイベントに対応します。
追加するように編集しました。これは、std::sort と連携して、今言ったことを実行するために作成したソート関数です。
template <class DataType, class IndexType>
class SortIndicesInc
{
protected:
DataType* mData;
public:
SortIndicesInc(DataType* Data) : mData(Data) {}
Bool operator()(const IndexType& i, const IndexType& j) const
{
return mData[i]<mData[j];
}
};