2016-12-17 9 views
-1

私はペアの最初の値でペアのベクトルをソートしようとしています。私は既に投稿されているこれに関する他の質問への回答の助言に従おうとしましたが、何らかの理由でベクトルを並べ替えるのに問題があります。私はstd :: sortとstd :: stable_sortを無駄に使用しようとしました。コードは正常にコンパイルされ、不満なく実行されますが、配列はソートされません。私のサンプルコードは以下の通りです:ペアのベクトルを最初の要素で並べ替えるにはどうすればいいですか?

#include <iostream> 
#include <vector> 
#include <algorithm> 

bool compare(const std::pair<int, int>&i, const std::pair<int, int>&j){ 
    return i.first < j.first; 
} 

int main(){ 
    std::vector<std::pair<int, char>> vec; 
    vec.reserve(10); // reserve space for 10 elements 
    int i; 
    std::string letters = "abcdefghij"; 
    int randNum; 

    for(i=0; i<10; i++){ 
    randNum = std::rand()%(10-0 + 1); // generate random numbers between 0 and 10 
    vec[i].first = randNum; // assign random integer to first element of pair 
    vec[i].second = letters[i]; // assign letter to second element of pair 
    } 

    for(i=0; i<10; i++){ // print out unsorted array 
    std::cout << vec[i].first << " " << vec[i].second << "\n"; 
    } 
    std::cout << "\n"; 
    std::sort(vec.begin(), vec.end(), compare); 

    for(i=0; i<10; i++){ // print out sorted array 
    std::cout << vec[i].first << " " << vec[i].second << "\n"; 
    } 

    return 1; 
} 

結果の出力はそうのようになります。

10 a 
1 b 
0 c 
6 d 
8 e 
3 f 
2 g 
0 h 
9 i 
4 j 

10 a 
1 b 
0 c 
6 d 
8 e 
3 f 
2 g 
0 h 
9 i 
4 j 
+4

コードは未定義の動作を示します。ベクトルのサイズは、ソート前、ソート中、ソート後に0です。バッファの最後を過ぎて要素にアクセスしています。 'vec.reserve(10);を' vec.resize(10);に置き換えてください –

+0

ありがとう、それは私の問題を解決しました! – SomeRandomPhysicist

答えて

2

あなたが実際にベクトルのサイズを変更していない、あなたのベクトルは空です。

の代わりに:

vec.reserve(10); 

用途:あなたはあなたのを置き換えることができ

// This won't print anything out at all. 
for (const auto &it : vec) { 
    std::cout << it.first << " " << it.second << "\n"; 
} 
+0

また、 'reserve'と' push_back'を使用してください。 – Oktalist

+0

あなたの答えをありがとう、それは確かに問題でした。このような問題を回避するには、ループの範囲ベースの方法が標準的な方法ですか? – SomeRandomPhysicist

+0

範囲ベースのforループは、タイプミスや間違いの可能性が少ないため、他のタイプのループよりもエラーが起こりにくいです。配列境界をハードコーディングすることは、ほとんど常に悪い考えです。 –

1

:あなたは範囲ベースのforループを使用した場合

vec.resize(10); 

これは明らかにされているだろうforループでは、push_backへのインデックスを使用してベクトルを初期化します。

for (i = 0; i<10; i++) { 
     randNum = std::rand() % (10 - 0 + 1); // generate random numbers between 0 and 10 
     vec.push_back(std::make_pair(randNum, letters[i])); // assign random integer to first element of pair 
                  // assign letter to second element of pair 
    } 
1

C++を学び始めたら、C++ 11の機能を学びます。コードを書くのが簡単になり、バグも少なくなります。これはあなたのプログラムであるIMOを書いた方がはるかに良い方法であり、あなたが持っていたバグに対処します。また、主に返る0は「ok」を意味し、1は「not ok」を意味します。

#include <iostream> 
#include <vector> 
#include <algorithm> 

int main() { 
    std::vector<std::pair<int, char>> vec; 
    std::string letters = "abcdefghij"; 

    for(auto l: letters) { 
    int randNum = std::rand()%(10-0 + 1); // generate random numbers between 0 and 10 
    vec.push_back({randNum, l}); // use constructor to create the pair 
           // pushback figures it is a pair that must be 
           // inserted and calls corresponding constructor (pair 
           // in this case) 
    } 

    for(auto p: vec) { 
    std::cout << p.first << " " << p.second << "\n"; 
    } 

    std::cout << "\n"; 

    std::sort(vec.begin(), vec.end(), [](auto a, auto b) { // use lambda. Cleaner and easier to read 
    return a.first < b.first; 
    }); 

    for(auto p: vec) { 
    std::cout << p.first << " " << p.second << "\n"; 
    } 

    return 0; 
} 
関連する問題