2014-09-18 131 views
13

變量x是一個向量n整數,我想按升序排列向量。然而,由於這個問題的範圍之外的原因,我想矢量保持不變。因此,我不想實際排序x的內容,我想創建另一個n指數矢量,其中每個指數指的是x中的相應值,如果x已被排序。創建一個排序向量索引的向量

例如:

std::vector<int> x = {15, 3, 0, 20}; 
std::vector<int> y; 
// Put the sorted indices of x into the vector y 
for (int i = 0; i < 4; i++) 
{ 
    std::cout << y[i]; 
} 

應該給輸出:

2 
1 
0 
3 

值相對應的在X:

0 
3 
15 
20 

我能想到很多實現這種及時途徑,但我想知道STL是否有內置的東西能夠爲我有效地執行此操作?

+2

我想你可以通過提供你自己的比較器來使用'std:sort',它可以將目標解引導到目標'std :: vector'中.. – Galik 2014-09-18 20:29:29

+0

請參閱http://stackoverflow.com/questions/1577475/c-sorting - 保持軌道指數 – sfjac 2014-09-18 20:42:52

回答

16

1)作爲索引的矢量創建y(整數範圍)

2)排序該範圍內的一個比較器,其從x 返回索引元件使用標準庫,給出:

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

int main() { 

    std::vector<int> x = {15, 3, 0, 20}; 

    std::vector<int> y; 

    std::vector<int> y(x.size()); 
    std::size_t n(0); 
    std::generate(std::begin(y), std::end(y), [&]{ return n++; }); 

    std::sort( std::begin(y), 
       std::end(y), 
       [&](int i1, int i2) { return x[i1] < x[i2]; }); 

    for (auto v : y) 
     std::cout << v << ' '; 

    return 0; 
} 

Live demo.

+1

感謝您的現場演示鏈接 - 不知道該網站! – Karnivaurus 2014-09-18 20:43:59

+0

lambdas也是不錯的例子。 – 2014-09-18 20:48:23

+0

如果將陣列更改爲{15,3,0,20,2,77},則不正確 – sh1ng 2016-07-29 23:23:41

8

填充yx所有索引,然後使用上ystd::sort,但提供的相應元素x進行比較的比較:

std::vector<int> y(x.size()); 
    std::iota(y.begin(), y.end(), 0); 
    auto comparator = [&x](int a, int b){ return x[a] < x[b]; }; 
    std::sort(y.begin(), y.end(), comparator); 
0

你可以做一個排序到另一個名單則與未分類的比較名單,然後一個第三列表,其中可以存儲索引,即nlog(n) + n^2或只是O(n^2)

注:這是僞代碼

vector<int> x = {15, 3, 0, 20}; 
vector<int> y = sort(x); 
vector<in> z; 
for(int i = 0; y < y.size(); i++){ 
    for(int j = 0; j < y.size(); j++){ 
     if(y[i] == x[j]){ 
     z.push_back(j); 
     } 
    } 
} 
4

您可以提供自己的比較,而分類索引的矢量,而像這樣的檢查目標載體的價值觀:

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

struct IdxCompare 
{ 
    const std::vector<int>& target; 

    IdxCompare(const std::vector<int>& target): target(target) {} 

    bool operator()(int a, int b) const { return target[a] < target[b]; } 
}; 

int main() 
{ 
    std::vector<int> x = {15, 3, 0, 20}; 
    std::vector<int> y; 

    // initialize indexes 
    for(size_t i = 0; i < x.size(); ++i) 
     y.push_back(i); 

    std::sort(y.begin(), y.end(), IdxCompare(x)); 

    std::cout << "\nvector x: " << '\n'; 
    for(size_t i = 0; i < x.size(); ++i) 
     std::cout << x[i] << '\n'; 

    std::cout << "\nvector y: " << '\n'; 
    for(size_t i = 0; i < x.size(); ++i) 
     std::cout << y[i] << '\n'; 

    std::cout << "\nvector x through y: " << '\n'; 
    for(size_t i = 0; i < x.size(); ++i) 
     std::cout << x[y[i]] << '\n'; 
} 

OUTPUT:

vector x: 
15 
3 
0 
20 

vector y: 
2 
1 
0 
3 

vector x through y: 
0 
3 
15 
20 
1

我們可以採取「直接引用「方法並使用指向源矢量中值的指針數組。

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

int main(int argc, const char * argv[]) { 
    //a source vector, who's order shouldn't be changed 
    std::vector<int> values = {15, 4, 20, 25, 0, 19, -5}; 
    //a vector of pointers to the values in the source vector 
    std::vector<int *> pointersToValues; 
    pointersToValues.reserve(values.size()); 

    for(auto& value : values){ 
     pointersToValues.push_back(&value); 
    } 

    //two comparators in form of lambda functions 
    auto descendingOrderSorter = [](int * i, int * j){ 
     return *i > *j; 
    }; 

    auto ascendingOrderSorter = [](int * i, int * j){ 
     return *i < *j; 
    }; 

    //examples of usage 
    std::cout<<"Sorting in a descending order"<<std::endl; 
    std::sort(pointersToValues.begin(), pointersToValues.end(), descendingOrderSorter); 
    for(int i = 0; i < pointersToValues.size(); ++i) { 
     std::cout << "index: " << i << ", value: " << *pointersToValues[i] << std::endl; 
    } 

    std::cout<<"Sorting in an ascending order"<<std::endl; 
    std::sort(pointersToValues.begin(), pointersToValues.end(), ascendingOrderSorter); 
    for(int i = 0; i < pointersToValues.size(); ++i) { 
     std::cout << "index: " << i << ", value: " << *pointersToValues[i] << std::endl; 
    } 

    return 0; 
} 

pointersToValues [I]會給你一個指向原始值,* pointersToValues [I]會給你的價值。