首页 > 解决方案 > 将 std::map 转换为有序的 std::vector

问题描述

我有一个std::map存储字符串和类的,我想根据类属性的值制作一个有序向量。但是,当我遍历向量时,什么都不会打印。到目前为止,我的代码是这样的,编译器没有发现错误:

void Championship::orderTeams(std::vector<std::pair<std::string, class Team> > vect, std::map<std::string, class Team>& map) {
    for (auto const& entry : map)
    {
        if (vect.empty()) { //check if vector is empty and add the first pair
            vect.push_back(std::make_pair(entry.first, entry.second));
            continue;
        }

        for (auto pos = vect.begin(); pos != vect.end(); ++pos) {
            if(entry.second.points > pos->second.points){
                vect.insert(pos, std::make_pair(entry.first, entry.second));

            }else if (pos==vect.end()){
                //vect.insert(pos, std::make_pair(entry.first, entry.second)); //wanted to check if there's a differance between insert and push_back
                vect.push_back(std::make_pair(entry.first, entry.second));
            }
        }
    }
}

Team仅包含 3 个公共int值(pointsgoalsTakengoalsGiven,构造函数和析构函数。

调用对的向量,teamOrdered我使用以下方法打印:

    for (const auto & team : teamOrdered){
        std::cout<<team.first<<" "<<team.second.points<<" "<<team.second.goalsScored<<" "<<team.second.goalsTaken<<std::endl;
    }

标签: c++dictionaryvector

解决方案


您的代码中存在一些问题。首先,根本没有输出的原因是因为vector是按值传入的;vect因此,对函数内部的任何更改都将丢失。您想通过引用传递它。您也可以通过const引用传递地图,因为您不需要更改地图。

最重要的是,您的排序方法实际上不起作用。考虑内部 for 循环的条件,pos != vect.end(); 但是,您有一个else ifwhich is pos == vect.end(),这根本是不可能的。此外,即使在添加元素之后,您仍会继续尝试将其添加到vect,并使用可能无效的迭代器(插入 avector可能会导致迭代器无效)。

这是您的代码的工作示例:

void Championship::orderTeams(std::vector<std::pair<std::string, Team>> &vect, const std::map<std::string, Team>& map) {
    for (auto const& entry : map)
    {
        if (vect.empty()) { //check if vector is empty and add the first pair
            vect.push_back(std::make_pair(entry.first, entry.second));
            continue;
        }

        bool added = false;
        for (auto pos = vect.begin(); pos != vect.end(); ++pos) {
            if(entry.second.points > pos->second.points){
                vect.insert(pos, std::make_pair(entry.first, entry.second));
                added = true;
                break;
            }
        }
        if (!added){
            vect.push_back(std::make_pair(entry.first, entry.second));
        }
    }
}

这也可以简化,使用std::sort来自algorithm标头,而不是接受一个向量,你可以返回一个。

std::vector<std::pair<std::string, Team>> orderTeams2( const std::map<std::string, Team>& map) {
    std::vector<std::pair<std::string, Team>> vect = { map.begin(), map.end() };
    std::sort( vect.begin(), vect.end(), []( auto &left, auto &right ) {
        return left.second.points > right.second.points;
    });
    return vect;
}

推荐阅读