【问题标题】:exchange key and vals in a map在地图中交换键和值
【发布时间】:2013-05-07 06:32:39
【问题描述】:

我有一张带有 (xi,f(xi)) 的地图,我的 f(xi) 也在严格增加。我需要以这种方式交换 key 和 vals

我的函数的输入:

带有

的地图
//keys :  x0,       x1,     x2,     ...,        xn
// vals :  f(x_0)   f(x1),  f(x2),  ...,        f(xn)

我的函数的输出: 一张地图

// key : left_val f(x_0)    f(x1),  ...,        f(xn-1)
// vals : x0,       x1,     x2,     ...,        xn

(这里left_val是一个输入参数,我知道它低于f(x0))。 我知道我可能没有使用正确的结构,但我真的需要 log(n) 插入和有序键的唯一性......

您将如何有效地实现这一点(即不复制地图)?

提前致谢。

【问题讨论】:

  • 你到底想做什么??
  • @Mario 我更改了函数的输入输出规范。是不是更清楚了?
  • 你已经给出了 'left_val' 并寻找 'f(x_n)
  • 作为算法问题还是使用标准库容器?
  • @DyP:如果元素已经排序(因为它们在这里),您可以在 O(n) 时间内构建一个新地图,并且您向insert 提供提示,每个都应该放在最后.

标签: c++ map


【解决方案1】:

这是一种不寻常的情况,因为您想要更改 std::map 键,这通常是禁止的,以避免会破坏排序的更改。如果您有信心自己确保这个不变量,那么您可以修改std::map,如下所示:

#include <iostream>
#include <map>

int main()
{
    typedef std::map<double, double> Mdd;

    Mdd m;
    m[1] = 4;
    m[2] = 6.5;
    m[3] = 7.2;
    m[4] = 9.3;
    m[5] = 12;

    double x = 2.3;

    for (Mdd::iterator i = m.begin(); i != m.end(); ++i)
    {
        double old_second = i->second;
        i->second = i->first;
        const_cast<double&>(i->first) = x;
        x = old_second;
    }

    for (Mdd::const_iterator i = m.begin(); i != m.end(); ++i)
        std::cout << i->first << "->" << i->second << '\n';
}

输出:

2.3->1
4->2
6.5->3
7.2->4
9.3->5

所有这一切都是使用const_cast 来坚持对密钥的写访问权。严格来说,我怀疑标准不需要实现在这样的骇客之后才能工作,但实际上我无法想象一个不需要的实现。你需要决定你想用x的最终值做什么——在你的问题中是f(xn)...我已经按照你的问题的建议丢弃了它。

就效率而言,这会按顺序传递map,如果希望使用这样的容器,这是不可避免的。没有映射的复制或额外的堆分配。转换后,根据上面关于标准不保证支持的警告,您可以期望有一个“正常”的有效地图,可以在其中安全地插入和删除元素。

【讨论】:

  • 非常感谢,这正是我想要的。棘手。这也可以用来回答这个问题stackoverflow.com/questions/5743545/…?
  • @robingirard:很好,它有帮助:-)。关于链接的问题,可以使用这种方法,但是需要更改键的新旧有序位置之间的键和值:如果新键在排序中的位置大致相同,那就太好了,但是如果节点之间的距离超过几个元素,我预计它会比erase/insert 替代方案慢(确切的阈值取决于新/删除和键/值复制性能等)。问题要求的是进行两次 log2N 查找并保持中间节点不变:更普遍有用。
【解决方案2】:

在新地图中插入新条目时,使用binary search algorithm 进行插入。每次插入都是 O(log n),重新创建地图的总时间应该是 O(n log n)。

【讨论】:

  • 如果条目已经排序,为什么还需要二进制搜索?按顺序插入它们,并提示它们应该放在最后,您将获得线性复杂度。为什么还要使用带有地图的二进制搜索呢?它会自动对元素进行排序。
  • 从问题中我认为问题在于实现一个自定义映射,该映射将元素按键递增的顺序放置在表中。 O(log n) 时间让我想到了二分搜索,但你说得对,这不适用于 f(xi) 也严格增加的情况。
猜你喜欢
  • 2013-03-13
  • 1970-01-01
  • 2014-03-12
  • 2011-05-25
  • 2018-06-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-09
相关资源
最近更新 更多