2013-07-12 3 views
4

Я хочу отсортировать std::vector используя сохраненные значения без потери информации индекса. Например,сортировать std :: vector без потерь индекс info

std::vector <int> vec; 
vec.resize(3); 
vec[0] = 20; 
vec[1] = 10; 
vec[2] = 6; 
std::sort(vec.begin(), vec.end()); 
// Here I want to know the order of indices after sort operation which is 2, 1, 0 
+3

Возможно, вы могли бы создать отдельный вектор индексов и 'sort()' этот вектор с пользовательским компаратором, который сравнивает индексированные значения, а не сами индексы? –

+4

Или у вас есть 'vector'' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '', ' Затем компаратор, который просто сравнивается с первым элементом. Не красиво. – BoBTFish

+3

Вам нужно отсортировать элементы, или вы хотите знать индексы элементов после сортировки, или и то, и другое? –

ответ

11

Вы хотите сохранить перестановку вашего исходного вектора, так что вам нужен другой вектор, который строит правильную биекцию из {0, ... , n - 1} в {0, ... , n - 1}:

vector<unsigned int> permutation(vec.size()); 
for(unsigned int i = 0; i < vec.size(); ++i) 
    permutation[i] = i; 

Мы не permutate что-нибудь еще. Теперь вы не сортировать второй вектор, вместо того, чтобы сортировать перестановку:

std::sort(permutation.begin(), permutation.end(), cmp); 

Если вы используете C++ 11, cmp может быть лямбда:

[&vec](unsigned int a, unsigned int b) { return vec[a] < vec[b];} 

Если вы используете C++ 03 вам нужно использовать с bool operator()(unsigned int, unsigned int)-структуру:

struct comparator{ 
    comparator(vector& v) : lookup(v){} 
    bool operator()(unsigned int a, unsigned int b){ 
     return lookup[a] < lookup[b]; 
    } 
    vector& lookup; 
}; 

comparator cmp(vec); 

отсортированный вектор может быть пройден с vec[permutation[i]].

+0

Я всегда смущаюсь использовать ссылки в качестве членов. –

+1

@MooingDuck: Верно, но вы бы выбрали 'vector *' как альтернативу? Копия может быть слишком дорогой. – Zeta

+0

Если бы я делал это, да, я бы сделал «вектор» из-за этого колебания. (Не сказать, что мой путь лучше, просто я бы так поступил). Тогда мой сравнитель будет копировать/переносить назначаемым как только указатель, в то время как ваш не копирует/переносит назначаемый вообще. OTOH, нет никакой причины для сопоставителя для копирования/перемещения, поэтому здесь нет ничего плохого в вашем дизайне. –

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