【问题标题】:Erase those values that already exists in other key's values in map c++擦除map c ++中其他键值中已经存在的那些值
【发布时间】:2019-02-16 05:37:02
【问题描述】:

假设我有一张地图,其值如下所述:

std::map<int, std::set<int>> myMap;
key 0: 1,2,3,4,5,6,7,8,9,10
key 1: 1,2,3,4,5,6
key 2: 4,5,6,7
key 3: 6,7

现在,我想删除键 0 中的所有值,这些值存在于它后面的其他键中。对于键 1 类似,依此类推。 所以,最终的输出(myMap)应该是这样的:

key 0: 8,9,10
key 1: 1,2,3
key 2: 4,5
key 3: 6,7

据我所知,按地图中的值进行搜索并不容易。对于我的代码,按值搜索是不可行的,因为我的数据非常大。这将非常耗时。

有没有更好的方法来做到这一点,而无需遍历以下每个键中的每个值来删除公共值?

【问题讨论】:

  • 他们是如何进入地图的?
  • 这些值实际上是我在应用程序中拥有的每个循环的基本块。我从支持工具中得到它。插入时无法进行检查,因为我使用的是其他工具提供的数据。
  • 您打算如何在不实际检查那些 key 的情况下找出任何 key 中是否存在 x?根据物理定律,这根本不可能。如果您愿意,可以通过在第二个容器中创建某种索引来加快它的速度,并且如果值得为创建所述索引增加内存/时间成本 - 如果您只这样做一次,那么不太可能。
  • 当您使用数据时,在运行中执行此操作确实可能更容易,但如果不知道您要做什么,就不可能说出来。 minimal reproducible example 会有所帮助。

标签: c++ c++11 stl stdmap


【解决方案1】:
std::set<int> to_remove;
for(auto&& e:backwards(myMap)) {
  std::set<int> r;
  std::set_difference(
    r.second.begin(), r.second.end(),
    to_remove.begin(), to_remove.end(),
    std::inserter(r)
  );
  std::copy(r.second.begin(), r.second.end(), std::inserter(to_remove));
  r.second = std::move(r);
}

backwards 在哪里:

template<class It>
struct range_t {
  It b, e;
  It begin() const { return b; }
  It end() const { return e; }
};
template<class C>
auto backwards( C& c )
-> range_t< typename C::reverse_iterator  >
{
  return {c.rbegin(), c.rend()};
}
template<class C>
auto backwards( C const& c )
-> range_t< typename C::const_reverse_iterator >
{
  return {c.rbegin(), c.rend()};
}

这使得向后迭代容器快速而简单。

这是 O(nlgn),而您的解决方案是 O(n^2lgn)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 1970-01-01
    • 2011-10-28
    相关资源
    最近更新 更多