2016/6/21 【c++】vectorとsortの謎(一部の区間だけをソートしたい!)
c++で動的配列を使いたいなと思ったときは、
#include をしてvectorを使うのが凄く便利なのでいつも使っています。
また、vectorの中の要素を並び替えたい時には
#include をしてsort関数を使うのが便利なのでこれも愛用しています。
sort関数の使い方としては、例えば以下のようなプログラムを組むと
0 1 2 3 4 6 9
となります。
このように、第一引数に目的のvectorの.begin()、第二引数に.end()を指定することで
そのvector型変数の要素全てを昇順に並び替えることが出来ます。
また、sortで並びえることが出来るのはvector型のみというわけではなく、
普通の配列もコメント部分のようにすれば並び替えることが可能です。
さらに、sort関数では配列の要素の一部分のみをソートすることもできるので、
最初の2つの要素だけをソートさせたいなと思い、こんなコードを書いたのですが
6 4 9 2 0 3 1
となります。
ん!?という感じがしませんか?
また、プログラム9行目のsort()の部分を
sort(v.begin() + 1, v.begin() + 4); とした時の出力は
6 2 4 9 0 3 1
となります。
あれあれ!?と思いませんか?
不思議に思ったので、c++のリファレンスが載っている下のサイトを見てみることにしました。
http://www.cplusplus.com/reference/algorithm/sort/
sort関数の第一引数には区間の最初の位置のfirst、
第二引数には区間の最後の位置のlastを指定しなさいとのことですが、
"The range used is [first,last), which contains all the elements between first and last,
including the element pointed by first but not the element pointed by last."
という文章が載っています。
つまり、sortの第二引数で指定した部分はソートされず、
その1つ前までの区間がソートされるらしいのです。
それって直感的じゃなくないか!?という気がしないでもないですが、
例えば配列の前半部分と後半部分をそれぞれ分けてソートしたいことがあった場合に
下のような書き方をすると
4 5 6 1 2 3
となります。
もし、sort関数の第二引数が指定した部分を含める方法だったとすると、
9行目のソートで配列の要素が
3 4 5 6 2 1
となり、10行目のソートで
3 4 5 1 2 6
となってしまいそうな感があるので、確かに理にかなってるのかなぁと思いました。
#include
また、vectorの中の要素を並び替えたい時には
#include
sort関数の使い方としては、例えば以下のようなプログラムを組むと
#include < vector > #include < iostream > #include < algorithm > using namespace std; int main() { vector< int > v = {6, 4, 9, 2, 0, 3, 1}; //int arr[] = { 6, 4, 9, 2, 0, 3, 1 }; sort(v.begin(), v.end()); //sort(arr, arr + sizeof(arr) / sizeof(int)); for (int i = 0; i < v.size(); i++){ cout << v[i] << " "; } cout << endl; return 0; }出力結果は
0 1 2 3 4 6 9
となります。
このように、第一引数に目的のvectorの.begin()、第二引数に.end()を指定することで
そのvector型変数の要素全てを昇順に並び替えることが出来ます。
また、sortで並びえることが出来るのはvector型のみというわけではなく、
普通の配列もコメント部分のようにすれば並び替えることが可能です。
さらに、sort関数では配列の要素の一部分のみをソートすることもできるので、
最初の2つの要素だけをソートさせたいなと思い、こんなコードを書いたのですが
#include < vector > #include < iostream > #include < algorithm > using namespace std; int main() { vector< int > v = {6, 4, 9, 2, 0, 3, 1}; sort(v.begin(), v.begin() + 1); for (int i = 0; i < v.size(); i++){ cout << v[i] << " "; } cout << endl; return 0; }このプログラムの出力結果は
6 4 9 2 0 3 1
となります。
ん!?という感じがしませんか?
また、プログラム9行目のsort()の部分を
sort(v.begin() + 1, v.begin() + 4); とした時の出力は
6 2 4 9 0 3 1
となります。
あれあれ!?と思いませんか?
不思議に思ったので、c++のリファレンスが載っている下のサイトを見てみることにしました。
http://www.cplusplus.com/reference/algorithm/sort/
sort関数の第一引数には区間の最初の位置のfirst、
第二引数には区間の最後の位置のlastを指定しなさいとのことですが、
"The range used is [first,last), which contains all the elements between first and last,
including the element pointed by first but not the element pointed by last."
という文章が載っています。
つまり、sortの第二引数で指定した部分はソートされず、
その1つ前までの区間がソートされるらしいのです。
それって直感的じゃなくないか!?という気がしないでもないですが、
例えば配列の前半部分と後半部分をそれぞれ分けてソートしたいことがあった場合に
下のような書き方をすると
#include < vector > #include < iostream > #include < algorithm > using namespace std; int main() { vector< int > v = {6, 5, 4, 3, 2, 1}; sort(v.begin(), v.begin() + v.size() / 2); sort(v.begin() + v.size() / 2, v.end()); for (int i = 0; i < v.size(); i++){ cout << v[i] << " "; } cout << endl; return 0; }出力結果は
4 5 6 1 2 3
となります。
もし、sort関数の第二引数が指定した部分を含める方法だったとすると、
9行目のソートで配列の要素が
3 4 5 6 2 1
となり、10行目のソートで
3 4 5 1 2 6
となってしまいそうな感があるので、確かに理にかなってるのかなぁと思いました。
-
Please
- feedly
- hatena bookmark
- Google plus
Share!