有没有办法在 C++ 中更新成对向量中的一对
Is there a way to update a pair in a vector of pairs in C++
此函数尝试找到一种方法来规划给定两个向量 A 和 B 的旅程,A[i] 是旅行的起点,B[i] 是旅行的目的地。
这是代码,但它似乎陷入了无限循环,因为成对的值没有得到更新。
vector<string> solve(vector<string> A, vector<string> B) {
unordered_map<string, vector<pair<string, char>>> map;
auto f = map.find(A[0]);
for(int i = 0; i < A.size(); i++){
f = map.find(A[i]);
if(f == map.end())
map[A[i]] = {make_pair(B[i], 'r')};
else
(f->second).push_back(make_pair(B[i], 'r'));
}
auto cmpfn = [](pair<string, char> x, pair <string, char> y){return x.first < y.first;};
for(auto f = map.begin(); f != map.end(); f++){
sort((f->second).begin(), (f->second).end(), cmpfn);
}
vector<string> res;
auto start = map[A[0]];
string dst;
int i;
res.push_back(A[0]);
while(true){
for(i = 0; i < start.size(); i++){
cout << start[i].first << " " << start[i].second << endl;
if(start[i].second == 'r'){
dst = start[i].first;
start.at(i).second = 'b'; // can't be updated
break;
}
}
if(i == start.size())
break;
res.push_back(dst);
start = map[dst];
}
cout << endl;
return res;
}
有人可以帮我找出为什么无法更新该对中的值并提出更好的方法吗?
编辑:我可以通过将 auto start = map[A[0]];
更改为 vector<pair<string, char>> &start = map[A[0]];
来解决问题,因为我在之前的方法中只是更新了 vector
的副本。
您的代码对所有涉及的对象进行了大量 复制,因此尝试对这些对象进行修改并没有达到您想要的效果是有道理的。您需要使用 references/pointers 来避免这些副本。
尝试更像这样的东西:
vector<string> solve(const vector<string> &A, const vector<string> &B) {
if (B.size() < A.size()) throw invalid_argument("B has fewer elements than A");
unordered_map<string, vector<pair<string, char>>> map;
for(size_t i = 0; i < A.size(); ++i) {
map[A[i]].push_back(make_pair(B[i], 'r'));
}
auto cmpfn = [](const pair<string, char> &x, const pair<string, char> &y){ return x.first < y.first; };
for(auto &elem : map) {
sort(elem.second.begin(), elem.second.end(), cmpfn);
}
vector<string> res;
string dst = A[0];
do {
auto &start = map[dst];
res.push_back(dst);
size_t i;
for(i = 0; i < start.size(); ++i) {
auto &p = start[i];
cout << p.first << " " << p.second << endl;
if (p.second == 'r') {
dst = p.first;
p.second = 'b';
break;
}
}
if (i == start.size()) break;
}
while (true);
cout << endl;
return res;
}
此函数尝试找到一种方法来规划给定两个向量 A 和 B 的旅程,A[i] 是旅行的起点,B[i] 是旅行的目的地。 这是代码,但它似乎陷入了无限循环,因为成对的值没有得到更新。
vector<string> solve(vector<string> A, vector<string> B) {
unordered_map<string, vector<pair<string, char>>> map;
auto f = map.find(A[0]);
for(int i = 0; i < A.size(); i++){
f = map.find(A[i]);
if(f == map.end())
map[A[i]] = {make_pair(B[i], 'r')};
else
(f->second).push_back(make_pair(B[i], 'r'));
}
auto cmpfn = [](pair<string, char> x, pair <string, char> y){return x.first < y.first;};
for(auto f = map.begin(); f != map.end(); f++){
sort((f->second).begin(), (f->second).end(), cmpfn);
}
vector<string> res;
auto start = map[A[0]];
string dst;
int i;
res.push_back(A[0]);
while(true){
for(i = 0; i < start.size(); i++){
cout << start[i].first << " " << start[i].second << endl;
if(start[i].second == 'r'){
dst = start[i].first;
start.at(i).second = 'b'; // can't be updated
break;
}
}
if(i == start.size())
break;
res.push_back(dst);
start = map[dst];
}
cout << endl;
return res;
}
有人可以帮我找出为什么无法更新该对中的值并提出更好的方法吗?
编辑:我可以通过将 auto start = map[A[0]];
更改为 vector<pair<string, char>> &start = map[A[0]];
来解决问题,因为我在之前的方法中只是更新了 vector
的副本。
您的代码对所有涉及的对象进行了大量 复制,因此尝试对这些对象进行修改并没有达到您想要的效果是有道理的。您需要使用 references/pointers 来避免这些副本。
尝试更像这样的东西:
vector<string> solve(const vector<string> &A, const vector<string> &B) {
if (B.size() < A.size()) throw invalid_argument("B has fewer elements than A");
unordered_map<string, vector<pair<string, char>>> map;
for(size_t i = 0; i < A.size(); ++i) {
map[A[i]].push_back(make_pair(B[i], 'r'));
}
auto cmpfn = [](const pair<string, char> &x, const pair<string, char> &y){ return x.first < y.first; };
for(auto &elem : map) {
sort(elem.second.begin(), elem.second.end(), cmpfn);
}
vector<string> res;
string dst = A[0];
do {
auto &start = map[dst];
res.push_back(dst);
size_t i;
for(i = 0; i < start.size(); ++i) {
auto &p = start[i];
cout << p.first << " " << p.second << endl;
if (p.second == 'r') {
dst = p.first;
p.second = 'b';
break;
}
}
if (i == start.size()) break;
}
while (true);
cout << endl;
return res;
}