次の整数の 2 次元配列があるとします。
1 3 3 1
1 0 2 2
2 0 3 1
1 1 1 0
2 1 1 3
ユーザーが配列自体と文字列を入力として与えることができる実装を作成しようとしていました。上記の例の文字列の例は03
、ユーザーが 1 番目と 4 番目の列に基づいて配列を並べ替えたいことを意味します。
したがって、この場合、ソートの結果は次のようになります。
1 1 1 0
1 3 3 1
1 0 2 2
2 0 3 1
2 1 1 3
STL の関数内で使用されている比較関数についてはあまり知りませんでしたが、sort
検索した結果、次の簡単な実装を作成しました。
というクラスを作りましたComparator.h
class Comparator{
private:
std::string attr;
public:
Comparator(std::string attr) { this->attr = attr; }
bool operator()(const int* first, const int* second){
std::vector<int> left;
std::vector<int> right;
size_t i;
for(i=0;i<attr.size();i++){
left.push_back(first[attr.at(i) - '0']);
right.push_back(second[attr.at(i) - '0']);
}
for(i=0;i<left.size();i++){
if(left[i] < right[i]) return true;
else if(left[i] > right[i]) return false;
}
return false;
}
};
文字列内の情報を知る必要があるため、この文字列がプライベート変数であるクラスが必要です。Iの内部operator
には と の 2 つのパラメーターがfirst
ありsecond
、それぞれが行を参照します。この情報を持って、ベクトルを作成します。left
ベクトルright
にleft
はfirst
、ソートに重要で文字列変数によって指定された行の番号のみがあり、right
ベクトルにsecond
は重要な行の番号のみがあります文字列変数で指定します。
次に、必要な比較を行い、true または false を返します。Sorting.cpp
ユーザーは、クラス内でこの関数を呼び出すことにより、このクラスを使用できます。
void Sorting::applySort(int **data, std::string attr, int amountOfRows){
std::sort(data, data+amountOfRows, Comparator(attr));
}
使用例を次に示します。
int main(void){
//create a data[][] variable and fill it with integers
Sorting sort;
sort.applySort(data, "03", number_of_rows);
}
2 つの質問があります。
最初の質問
実装を改善できますか? left
ベクトルやベクトルなどの追加の変数を使用しright
、さらに for ループをいくつか使用して、並べ替え操作に余分なコストがかかります。
2 番目の質問
余分なコストのために、ソートの時間の複雑さはどの程度悪化しますか? STLsort
はO(n*logn)
、n
並べ替えたい整数の数です。ここn
には異なる意味n
があります。行の数であり、各行はm
整数まで持つことができます。これはComparator
、関数をオーバーライドし、operator
追加の変数 (ベクトル) と for ループを使用することによって、クラス内で見つけることができます。
STL がどの程度正確に実装されているのかわからないsort
ため、いくつかの見積もりしかできません。私の最初の見積もりは、ソートに重要な列の数がO(n*m*log(n))
どこにm
あるかということですが、100%確実ではありません。
前もって感謝します