【问题标题】:How to change index values after sorting a vector? c++对向量进行排序后如何更改索引值? C++
【发布时间】:2019-11-20 19:29:59
【问题描述】:

我有一个pair<int, struct> 的向量,其中int 对应于索引。 我按struct 对这个向量进行排序,并希望我的输出向量的 int 值与新的排序相对应。

我该怎么做?

<1,zone> <2, car> <3, apple>  

排序为:

<3, apple>, <2, car>, <1, zone>

现在我想更改这些整数以对应于它们在向量中的新索引。即与 apple 的配对是 1。我该怎么做?

希望有一种 STL 方式,这样我就不会只是遍历向量并手动更改它们。

【问题讨论】:

  • 你为什么要这样做?您无需将索引存储在元素中即可获取它。如果你这样做&amp;reference_to_object_in_vector - &amp;vector_name[0],你会得到它的索引。
  • 如果需要,您可以随时使用计数器设置 .first = counter; 遍历向量...(但您真的不需要 std::pair,如果您只是关注std::string) 最近没有迭代的是std::transform——它只是为你做迭代。

标签: c++


【解决方案1】:

您总是可以在排序函数中添加重新索引。

void bubbleSort(vector);   //generic bubble sort
{  
    int i, j;  
    for (i = 0; i < vector.size()-1; i++){      
        for (j = 0; j < vector.size()-i-1; j++){
            if (vector[j].second > vector[j+1].second){  
                swap(&arr[j], &arr[j+1]);
                vector[j].first = j+1;   //
                vector[j+1].first = j;   // updating index values here 
             }
         }
     }
}  

或者你可以有一个简单的 for 循环遍历向量并重新索引它。

vector<pair<int, struct>> myvector;

for(int i = 0; i < myvector.size(); i++){
    myvector[i].first = i;
}

【讨论】:

    【解决方案2】:

    如果您仍然遇到问题,您可以使用std::sort 进行排序,并使用std::transform 重新排序从1 开始的索引部分,但需要-std=c++14 才能使用lambda 捕获初始化程序。否则,您将不得不使用循环来重新排序对索引。

    基本方法是:

        std::vector<std::pair<int, std::string>> vp {{1, "zone"}, 
                                                     {2, "car"},
                                                     {3, "apple"}};
        ...
        /* sort by string */
        std::sort (vp.begin(), vp.end(), [](const std::pair<int, std::string>& a, 
                                            const std::pair<int, std::string>& b) {
                                                return a.second < b.second; });
        /* reorder integers */
        std::transform (vp.begin(), vp.end(), vp.begin(), 
                        [n = 1](std::pair<int, std::string>& a) mutable { 
                            a.first = n++;
                            return a = {a.first, a.second}; });
    

    添加一小段输出以显示结果以及所需的标题,您可以这样做:

    #include <iostream>
    #include <utility>
    #include <vector>
    #include <algorithm>
    
    int main (void) {
    
        std::vector<std::pair<int, std::string>> vp {{1, "zone"}, 
                                                     {2, "car"},
                                                     {3, "apple"}};
        std::cout << "pre-sort/transform:\n";
        for (auto& i : vp)
            std::cout << i.first << ", " << i.second << '\n';
    
        /* sort by string */
        std::sort (vp.begin(), vp.end(), [](const std::pair<int, std::string>& a, 
                                            const std::pair<int, std::string>& b) {
                                                return a.second < b.second; });
        /* reorder integers */
        std::transform (vp.begin(), vp.end(), vp.begin(), 
                        [n = 1](std::pair<int, std::string>& a) mutable { 
                            a.first = n++;
                            return a = {a.first, a.second}; });
    
        std::cout << "\npost-sort/transform:\n";
        for (auto& i : vp)
            std::cout << i.first << ", " << i.second << '\n';
    }
    

    使用/输出示例

    $ ./bin/vectorpair
    pre-sort/transform:
    1, zone
    2, car
    3, apple
    
    post-sort/transform:
    1, apple
    2, car
    3, zone
    

    虽然使用std::vector&lt;std::pair&gt; 没有任何问题,但如果您没有对索引进行任何其他用途,请考虑使用简单的std::vector&lt;std::string&gt; 并取消std::pair。您可以随时在需要时生成索引。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 2012-08-16
      • 2018-05-12
      • 2021-12-22
      • 1970-01-01
      相关资源
      最近更新 更多