我有一张带有(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)插入和有序键的唯一性......
你如何有效地实现这一点(即不重复地图)?
提前致谢。
答案 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)。