Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/134.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在映射中交换密钥和VAL_C++_Map - Fatal编程技术网

C++ 在映射中交换密钥和VAL

C++ 在映射中交换密钥和VAL,c++,map,C++,Map,我有一张(xi,f(xi))的地图,我的f(xi)也在严格增加。我需要这样交换密钥和VAL 我的功能输入: 地图 //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,

我有一张(xi,f(xi))的地图,我的f(xi)也在严格增加。我需要这样交换密钥和VAL

我的功能输入:

地图

//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))。 我知道我可能没有使用正确的结构,但我确实需要有序密钥的日志(n)插入和唯一性

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


提前谢谢

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

在新映射中插入新条目时,请使用进行插入。每次插入都是O(logn),重新创建映射的总时间应该是O(nlogn)。

这是一种不寻常的情况,因为您想要更改
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';
}
所有这些都是使用
const\u cast
来坚持对密钥的写访问。严格地说,我怀疑在这种黑客攻击之后,标准不会要求实现工作,但在实践中,我无法想象一个实现不会工作。您需要决定如何处理
x的最终值
——您的问题是
f(xn)
。。。根据你的问题,我已经放弃了


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

这是一种不寻常的情况,因为您想要更改
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';
}
所有这些都是使用
const\u cast
来坚持对密钥的写访问。严格地说,我怀疑在这种黑客攻击之后,标准不会要求实现工作,但在实践中,我无法想象一个实现不会工作。您需要决定如何处理
x的最终值
——您的问题是
f(xn)
。。。根据你的问题,我已经放弃了



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

您到底想做什么???@Mario I更改了我函数的输入输出规范。更清楚吗?您已经给出了“左”值,并将“f(x_n)”作为算法问题或使用标准库容器来查找?@DyP:如果元素已经排序(如此处所示),您可以在O(n)时间内构建新地图您还提供了插入提示,提示每一个都应该放在末尾。您到底想做什么???@Mario我更改了我函数的输入输出规范。更清楚吗?您已经给出了“左”值,并将“f(x_n)”作为算法问题或使用标准库容器来查找?@DyP:如果元素已经排序(如此处所示),您可以在O(n)时间内构建新地图您还提供了插入提示,提示每个条目都应该放在末尾。如果条目已经排序,为什么需要进行二进制搜索?按顺序插入它们,并提示它们应该在末尾,您将得到线性复杂度。为什么要对地图使用二进制搜索呢?它会自动对元素排序。从这个问题上,我认为问题在于实现一个自定义映射,该映射将元素按键顺序递增地放入表中。O(logn)时间让我想到了二进制搜索,但你是对的,这不适用于f(xi)也严格增加的情况。如果条目已经排序,为什么需要二进制搜索?按顺序插入它们,并提示它们应该在末尾,您将得到线性复杂度。为什么要对地图使用二进制搜索呢?它会自动对元素排序。从这个问题上,我认为问题在于实现一个自定义映射,该映射将元素按键顺序递增地放入表中。O(logn)时间让我想到了二进制搜索,但你是对的,这不适用于f(xi)也严格增加的情况。非常感谢,这正是我想要的。棘手的这也可以用来回答这个问题?@Robingilard:很好,它有帮助:-)。关于链接问题,可以使用这种方法,但需要更改旧的和新的顺序键位置之间的键和值:如果新键在顺序中的位置大致相同,这很好,但是,如果节点之间的间隔超过几个元素,我希望它会比
擦除
/
插入
备选方案慢(确切阈值取决于新建/删除和键/值复制性能等)。问题是要有两个log2N查找,并保持中间节点不变:更普遍的有用。非常感谢,这正是我想要的。棘手的这也可以用来回答这个问题?@Robingilard:很好,它有帮助:-)。关于t