在地图中交换密钥和值

时间:2013-05-07 06:32:40

标签: c++ map

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

输入我的功能:

带有

的地图
//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)插入和有序键的唯一性......

你如何有效地实现这一点(即不重复地图)?

提前致谢。

2 个答案:

答案 0 :(得分:4)

这是一种不寻常的情况,因为您想要更改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来坚持对密钥的写访问。严格地说,我怀疑标准不会要求实施在这样的hackery之后工作,但在实践中我无法想象一个实现不会。您需要决定要对x的最终值做什么 - 在您的问题f(xn)中......我已根据您的问题建议将其丢弃。

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

答案 1 :(得分:1)

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