【问题标题】:The best practice for (unordered) map keys and values modification(无序)映射键和值修改的最佳实践
【发布时间】:2021-10-08 17:25:34
【问题描述】:

给出map<long long, vector<long long>> 形式的映射。必须将所有键和值取模某个整数N。一些键可以合并,相应的值必须相应地加入。例如,映射{{1,{2,6,4}}, {5,{8,4,9}}, {10,{5,1,7}}} 应该等于{{1,{2,1,4}}, {0,{0,1,2,3,4}}} 减少模5。

我的方法是使用新地图,但我认为应该有更好的方法。

添加代码

vector<long long> tmp;
//integer N, for example N = 5
int N = 5;
unordered_map<long long, vector<long long>> map;
//temporary map
unordered_map<long long, vector<long long>> map_tmp;
     for (auto & x : map)
        {
            tmp.clear();
            for (auto & y : x.second) tmp.push_back(y % N);
            ind = x.first % N;
            map_tmp[ind].insert(map_tmp[ind].end(), tmp.begin(), tmp.end());
            sort(map_tmp[ind].begin(), map_tmp[ind].end());
            map_tmp[ind].erase(unique(map_tmp[ind].begin(), map_tmp[ind].end()), map_tmp[ind].end());
        }
        map = map_tmp;

【问题讨论】:

  • 您可以使用 C++17 或更高版本吗?
  • 这对std::transform 来说似乎是一个沉重的负担。无论如何,如果您有工作 代码并且想知道如何改进它,这是code review 的问题。但请务必查看如何提问,因为特别是您需要发布代码,而不是非常简短的代码高级摘要。
  • 你做了什么?我看到了任务描述,但没有尝试解决它。​​
  • “应该相等”是否包括向量元素的顺序?
  • 地图中的键是const,至少你需要创建新元素,然后我看不到创建新地图的优势

标签: c++ unordered-map


【解决方案1】:

由于 map 中的值显然是唯一的,并且在应用模运算后值包含唯一项,因此您应该使用不同的数据结构。例如:

using Map = std::unordered_map<int, std::set<int>>;

std::set 将处理给定键的项目的唯一性和顺序。

现在整个技巧是检查std::unordered_mapstd::set 的API 以及如何将项目插入那里。见:

注意返回值:std::pair&lt;iterator,bool&gt;,它为您提供了在地图/集合中插入或令人兴奋的项目的迭代器。

知道编写能够满足您要求的代码非常简单:

using Map = std::unordered_map<int, std::set<int>>;

Map moduloMap(const Map& in, int mod)
{
    Map out;
    for (const auto& [k, s] : in) {
        if (s.empty())
            continue;
        auto& destSet = out.insert({ k % mod, {} }).first->second;
        for (auto x : s) {
            destSet.insert(x % mod);
        }
    }
    return out;
}

Live demo with tests

【讨论】:

  • 但您应该能够批准答案。奇怪的是 SO 有这个限制。如果我没记错的话,我开始的时候不是这样的
【解决方案2】:

有时for 循环可能是做某事的最简单、最清晰的方法。

map<long long, vector<long long>> result;
for (const auto& [key, vec] : input) {
    process (result[key%5], vec);
    }

process 通过(非常量)引用获取vector,并附加第二个(常量)参数的缩减值。


更新

看了你贴的代码,我有几个建议:

  1. 请改用set。您正在花费多个步骤来附加新值,将整个内容排序在一起,然后删除重复项。只需使用 set 即可自动维护每个值的单个副本。
  2. 在循环中使用结构化绑定。除了x.secondx.first,您只需将它们命名为keyvec,就像我之前的帖子中一样。
  3. 假设您仍然需要tmp,请在您现在调用.clear() 的位置声明它,而不是在代码顶部声明它。您不需要每次通过循环都清除它;每次循环自然都会为空。

【讨论】:

  • @463035818_is_not_a_number 我的代码也是。
  • @463035818_is_not_a_number input 不变。 result 填充了模键和合并的模值。我没有删除任何东西。
  • 啊,真的很抱歉。完全误读了代码。我应该休息一下
猜你喜欢
  • 1970-01-01
  • 2021-07-24
  • 2023-03-16
  • 1970-01-01
  • 2020-04-19
  • 2014-12-04
  • 1970-01-01
  • 1970-01-01
  • 2015-09-10
相关资源
最近更新 更多