假设:
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
答案 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
轮换。