2016-12-17 1 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); 

Использование:

vec.resize(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

Диапазоны, основанные на циклах, менее подвержены ошибкам, чем другие типы петель, поскольку возможностей для опечаток и ошибок меньше. Жесткое кодирование границ массива - почти всегда плохая идея. –

1

можно заменить for loop, где вы инициализируете вектор, используя индексы to 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 по умолчанию означает «ОК» и 1 означает «не нормально»

#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; 
} 

 Смежные вопросы

  • Нет связанных вопросов^_^