交换映射中的键和值

exchange key and vals in a map

本文关键字:键和值 映射 交换      更新时间:2023-10-16

我有一个映射(xi,f(xi)),我的f(xi)也严格增加。我需要这样交换键和值

我的函数输入:

带有

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

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

提前感谢。

这是一种不寻常的情况,因为您想要更改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上进行一次顺序传递,如果希望使用这样的容器,这是不可避免的。没有映射的复制或额外的堆分配。在转换之后,根据上面关于标准不保证支持的警告,您可以期望有一个"正常"的有效映射,其中可以安全地插入和删除元素。

在新映射中插入新条目时,使用二进制搜索算法进行插入。每次插入将是O(log n),重新创建映射的总时间应该是O(n log n)。