【问题标题】:Is there a way to update a pair in a vector of pairs in C++ [closed]有没有办法在 C++ 中更新对向量中的一对[关闭]
【发布时间】:2021-10-18 17:41:19
【问题描述】:

这个函数试图在给定两个向量 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&lt;pair&lt;string, char&gt;&gt; &amp;start = map[A[0]]; 来解决问题,因为在之前的方法中我只是更新了vector 的副本。

【问题讨论】:

  • map 存储向量的副本。分配给start 时,您还会再次复制。当然,当您返回 res 时,参数向量 A 和 B 也会被复制。所有这些复制都是有意(或需要)的吗?
  • 当您使用调试器一步一步地运行程序时,一次一行,并在每一行执行后检查所有变量的值,您看到了什么?
  • @Someprogrammerdude 不,我想更新 pair.second 的值以将其标记为已访问,这样我就不会重新访问它......那么有更好的方法吗?
  • @SamVarshavchik 我对 pair.second 的值保持不变,这就是存在无限循环的原因,(pair.second 用于标记访问的节点)我想要一种编辑它的方法...
  • 现在,您只需要弄清楚为什么它“保持不变”,这也是调试器帮助确定的事情。您的调试器有各种工具,例如显示每个变量的实际内存地址、设置观察点等...祝您好运!

标签: c++ stdvector unordered-map std-pair


【解决方案1】:

您的代码正在对所有涉及的对象进行大量副本,因此尝试修改这些对象并没有达到您想要的效果是有道理的。您需要使用引用/指针来避免这些副本。

尝试类似的方法:

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;
}

【讨论】:

  • lambda 中有更多的副本。元素是 std::pair,但它需要一个 non-const 字符串,因此会制作传入的对的完整副本,并且引用绑定到该临时文件。更好的是(对于 OP)首先不要创建或传递 lambda,因为 sort 已经使用 std::less&lt;&gt;,如果元素具有可比性,std::pair 开箱即用。
  • @ChrisUzdavinis 您可能会想到用于unordered_map::value_type 的pair,但这不是传递给lambda 的pair。 unordered_map::mapped_type 正在传递给 lamdba,而 pair 不使用 const 字符串。除了push_backs 之外,此代码中不应有任何副本。此外,pair 的 operator&lt; 将比较两个字段,但 OP 的 lambda 仅比较第一个字段。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多