[英]Transforming std::map into ordered std::vector
我有一个std::map
存储一个字符串和一个 class ,我想根据 class 属性的值创建一个有序向量。 但是,当我遍历向量时,什么都不会打印。 到目前为止,我的代码是这样的,编译器没有发现错误:
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));
}
}
}
}
Class Team
仅包含 3 个公共int
值( points
、 goalsTaken
和goalsGiven
)、构造函数和析构函数。
对的向量称为teamOrdered
,我使用以下方法打印:
for (const auto & team : teamOrdered){
std::cout<<team.first<<" "<<team.second.points<<" "<<team.second.goalsScored<<" "<<team.second.goalsTaken<<std::endl;
}
您的代码中存在一些问题。 首先,根本没有 output 的原因是因为vector
是按值传入的; 因此, vect
内部对 vect 的任何更改都将丢失。 您想通过引用传递它。 您也可以通过const
引用传递 map,因为您不需要更改 map。
最重要的是,您的排序方法实际上不起作用。 考虑内部 for 循环的条件pos.= vect.end()
; 但是,您有一个else if
是pos == vect.end()
,这根本是不可能的。 此外,即使在添加元素之后,您仍会继续尝试将其添加到vect
,并使用可能无效的迭代器(插入vector
可能会导致迭代器无效)。
这是您的代码的工作示例:
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));
}
}
}
这也可以简化,使用algorithm
header 中的std::sort
,而不是接受向量,您可以返回一个。
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;
}
正如其他人所指出的那样,因为您按值传递向量,所以没有打印任何内容。 通过引用传递它或返回向量。
此外,您可以使用std::sort
和谓词进行排序。 这是一个有效的解决方案:
#include <algorithm>
#include <iostream>
#include <map>
#include <vector>
class Team {
public:
int points;
int goalsTaken;
int goalsGiven;
};
void orderTeams(std::vector<std::pair<std::string, class Team> >& vect, std::map<std::string, class Team>& map) {
for(auto currentIterator = map.begin(); currentIterator != map.end(); ++currentIterator) {
vect.emplace_back(currentIterator->first, currentIterator->second);
}
std::sort(vect.begin(), vect.end(),
[](const std::pair<std::string, class Team>& item1, const std::pair<std::string, class Team>& item2) -> bool { return item1.second.points > item2.second.points; });
}
int main()
{
std::vector< std::pair<std::string, class Team>> teamOrdered;
std::map<std::string, class Team> map;
map.emplace(std::string("4"), Team{ 4, 4, 4 });
map.emplace(std::string("2"), Team{ 2, 2, 2});
map.emplace(std::string("1"), Team{ 1, 1, 1 });
map.emplace(std::string("3"), Team{ 3, 3, 3});
orderTeams(teamOrdered, map);
for(const auto& team : teamOrdered) {
std::cout << team.first << " " << team.second.points << " " << team.second.goalsGiven << " " << team.second.goalsTaken << std::endl;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.