使用stl :: map的std :: map rotate方法或算法

时间:2013-08-14 20:53:59

标签: c++ stl

我开发了一个类,里面有一个std :: map,现在功能是最优的,但是现在我需要旋转地图,我的意思是旋转变换顺序,地图元素除了对应的值之外以这些价值观为例:

假设:

Map[122]=1
Map[12]=2
Map[3]=45

应用旋转算法一次:

Map[12]=2
Map[3]=45
Map[122]=1

再次应用旋转算法:

好吧,我的第一个目的是编写一个执行此操作的算法,但我是c ++中的新手

Map[3]=45
Map[122]=1
Map[12]=2

我现在在stl libs中有一个我现在看不到的正确解决方案吗? THX

3 个答案:

答案 0 :(得分:4)

没有

地图元素的顺序不是您控制的。它是固有的,基于排序键。

当然,您可以提供自己的比较器,以便操纵容器的基础顺序。

但是,您应该依赖地图中的订单。它不是一个序列容器,并且根本不是为您使用order作为属性而设计的。

为什么不在每次容器中的不同位置开始迭代而不是“旋转”,而是“环绕”?

答案 1 :(得分:1)

我认为你可能会混淆“映射”与“存储”。在数学(或算法)意义上,如果您将一个键“映射”到一个值,那么这是一对一映射,直到它被更改,当您查找该键时,您将始终获得该值。它实际上是如何工作的,或者用于实现地图的任何对象是否“旋转”都没有关系。查找一个键,获取值。在你的情况下,在轮换之前或之后,如果你查看“12”,你将永远得到2.你看到我在说什么吗?在这里订购,没关系。因此,如果从STL使用std :: map,则会失去对存储元素的顺序的保证的控制。

现在,你所要求的与实现有关,尤其是元素的存储方式,所以你需要的是一个保证顺序的STL容器。一个这样的容器是矢量。在我看来,你可能想要的可能是对的矢量。这样的事情would work

#include <vector>
#include <map> //for std::pair
#include <iostream>
#include <algorithm> //for std::rotate

typedef std::pair<int,int> entry;
typedef std::vector<entry> storage;

void print( const char* msg, const storage& obj )
{
    std::cout<<msg<<std::endl;
    for(auto i : obj)
    {
        std::cout << i.first << "," << i.second << std::endl;
    }
}

void lookup(int key, const storage& obj)
{
    for(auto i : obj)
    {
        if( i.first == key )
        {
            std::cout<<"\t"<<key<<"=>"<<i.second<<std::endl;
            return;
        }
    }
    std::cout<<key<<"not found"<<std::endl;
}

int main()
{
    storage mymap = {entry(122,1),entry(12,2),entry(3,45)};
    print("Before rotation", mymap);
    lookup(12,mymap);
    std::rotate(mymap.begin(),mymap.begin()+1,mymap.end());
    print("After one rotation", mymap);
    lookup(12,mymap);
    std::rotate(mymap.begin(),mymap.begin()+1,mymap.end());
    print("After one more rotation", mymap);
    lookup(12,mymap);
    return 0;
}

但请注意,因为您使用的是矢量,所以它不会保护您不会添加具有不同键但具有相同值的重复对或对,反之亦然。如果要保持一对一映射,则必须确保在插入元素时,“键”和“值”不会在向量中的任何其他位置重复。在阅读了std::vector works之后,你应该很容易理解这一点。

答案 2 :(得分:0)

扩展Lightness的答案,我相信这是正确的答案。如果您无法控制地图,则应使用static matrix代替。

矩阵使用简单的数学运算提供了更多的旋转选项,而不是您尝试实现的cyclical轮换。