当前位置: 代码迷 >> C++ >> 状态枚举种Enumerator源代码,欢迎拍砖
  详细解决方案

状态枚举种Enumerator源代码,欢迎拍砖

热度:5501   发布时间:2013-02-26 00:00:00.0
状态枚举类Enumerator源代码,欢迎拍砖!
初衷是解决智力题中的较复杂的推理题,比如:
有5个人参加某项比赛,但是参赛人员必须满足:
1、如果A参加,则B一定参加
2、C和D有且只有一人参加
3、D和E要么都参加,要么都不参加
4、如果C参加,则B一定不参加
5、最多有两个人参加
问满足条件的参赛人选。
我知道Prolog擅于解决此类问题,但是我擅用的语言是C++,所以就有了下面的代码。至于实用于否就不管了,权当是做了一个codekata,欢迎大家拍砖!
我的空间里也有
我用的是VS2012,我必须要undef max才能使用std::limits<>::max()函数,很上火!

#pragma once

#include<limits>
#include<vector>
#include<string>
#include<boost/lexical_cast.hpp>
#undef max
template<unsigned int BASE, class TYPE=unsigned>
class Enumerator
{
static_assert(BASE > 2, "template parameter should greater than 2!");
public:
// typedef unsigned int TYPE;

Enumerator(unsigned int count, TYPE stat = 0)
{
status.clear();
status.resize(count, stat);
}
bool operator ++()
{
int c = 1;

for (size_t i = 0 ; c != 0 && i < status.size() ; ++i)
{
status[i] += c;
if(status[i] >= BASE)
{
status[i] = 0;
c = 1;
}
else
{//不需要再继续进位
c = 0;
}
}
return c == 0;
}
bool operator++(int)
{
return this->operator++();
}
TYPE get(size_t i) const
{
if(i >= status.size()) 
throw std::out_of_range(std::string("i should less than ") 
+ lexical_cast<string>(status.size()));
return status[i];
}
void set(size_t i, TYPE s)
{
if(i >= status.size()) 
throw std::out_of_range(string("i should less than ") 
+ lexical_cast<string>(status.size()));
status[i] = s;
}
size_t count(TYPE s) const
{
size_t result = 0;
for (const auto& p : status)
{
if(p == s) result++;
}
return result;
}
size_t size()  const
{
return status.size();
}
protected:
private:
std::vector<TYPE> status;
};
template<class T>
class Enumerator<2, T>
{
//只要是这种2状态的东西,直接采用unsigned类型,忽略类型参数T
typedef unsigned int TYPE;
public:
Enumerator(unsigned int count, bool statu = 0)
:SIZE(count)
{
status.clear();
status.resize(SIZE / BITS + 1, statu ? std::numeric_limits<TYPE>::max() : 0);
}
bool operator++()
{
static const auto MAX = std::numeric_limits<TYPE>::max();
int c = 1;

for (size_t i = 0 ; c != 0 && i < status.size() ; ++i)
{
if(status[i] == MAX)
{
status[i] = 0;
c = 1;
}
else
{
status[i]+=c;
c = 0;
}
}
return c == 0 && (status.back() >> (SIZE % BITS)) == 0;
}
bool operator++(int)
{
return operator++();
}
short get(size_t i) const
{
  相关解决方案