使用考虑了过渡或键值在std :: map中的换行的键

时间:2018-11-05 15:45:30

标签: c++ c++11 dictionary std stdmap

是否有一个std::map的密钥,该密钥考虑了密钥的滚动或换行?如果是这样,您将如何实现<运算符来做到这一点?

假设键是基于一个最大值为N的计数器,则可以有一个<运算符,该运算符会在键值翻转时加以考虑,以便在地图中按以下顺序对各项进行排序:< / p>

 N-2
 N-1
 N
 1
 2
 3
 ...

此外,如果可以跳过键值,是否可以这样做?例如,跳过N以便地图具有以下值:

 N-2
 N-1
 1
 2
 3
 ...

3 个答案:

答案 0 :(得分:0)

是的

利用<std::tuple的{​​{1}},您可以执行类似的操作

bool

See it live on coliru

答案 1 :(得分:0)

这里是如何实现此示例。这个想法是要引入一个自定义Key模板,该模板可以在编译时用所需的最大值进行参数设置。通过boost operator library提供比较和基本算术运算,以使Key实例具有相同的最大值。值可以进行比较和添加。

#include <boost/operators.hpp>

template <int max>
struct Key : private boost::totally_ordered<Key<max>, boost::addable<Key<max>>> {
   int value;

   Key(int init = 0) : value(init) { maybeRollOver(); }

   Key& operator+=(const Key& rhs) { value += rhs.value; maybeRollOver(); return *this; }
   const Key& operator+() const { return *this; }

   void maybeRollOver() { if (value > max) value = value % max - 1; }
};

此模板需要两个运算符重载才能生成所有比较运算符(请参见boost docs):

template <int max>
bool operator==(const Key<max>& lhs, const Key<max>& rhs)
{
   return lhs.value == rhs.value;
}

template <int max>
bool operator<(const Key<max>& lhs, const Key<max>& rhs)
{
   return lhs.value < rhs.value;
}

这是使用方法。

std::map<Key<5>, std::string> testMap;

testMap[0] = "Hello";
testMap[1] = "world";
testMap[6] = "Bye"; // "rolled over to 0, "Hello" is replaced by "Bye";

for (const auto& [key, value] : testMap)
   std::cout << key.value << ": " << value << "\n";

答案 2 :(得分:0)

这是我能够上班的解决方案。

密钥实际上是<unsigned int, unsigned int>,相对于翻转的顺序只需要考虑密钥的第一个值。 另外,该ID基于1,因此值将为1, 2, ..., N, 1, 2, ... 最后,请注意,MAX ID足够大,因此我们永远不会有多个相同的键试图同时存在于映射中。也就是说,当我们到达ID N时,最初的1、2、3 ...键早已消失。

class Mykey(
public:
   unsigned int Id1;
   unsigned int Id2;

MyKey(unsigned int k1, unsigned in k2)
: Id1(k1), Id2(k2) {}

bool operator<(const MyKey &rhs) const
{
    if (Id1 == rhs.Id1)
        return Id2 < rhs.Id2;
    else if ( (rhs.Id1 > Id1) && (rhs.Id1 - Id1 > MAX_ID/2) )
        return false;
    else if ( (Id1 > rhs.Id1) && (Id1 - rhs.Id1 > MAX_ID/2) )
        return true;
    else
        return Id1 < rhs.Id1;
}

假设MAX_ID为25,则第一个否则考虑rhs.Id1为25而Id1为1的情况。第二个其他情况考虑Id1 = 25而rhs.Id1 = 1的相反情况。 MAX_ID / 2正在检查两个值是否“相距较远”,以表示ID换行。