一、审题:
约瑟夫环,一共m个人围成一圈,从第一个开始数1,数到n的出圈,输出剩余n-1个人的原有编号。
例子:
50个人围一圈,从第一个开始数1,数到3的出圈,输出剩余2个人的原有编号。
二、代码结构:
1、使用类封装约瑟夫游戏,对外只暴露Game函数,用于调用约瑟夫游戏。
2、维护容器vector和约瑟夫3个功能函数,1个逻辑函数,这些组合在一起作为约瑟夫游戏的完整系统。
三、功能函数和逻辑函数组成的完整系统
1、组合成环
这个函数用于提供一个数量适合的约瑟夫环,并且保证每次提供的约瑟夫环时全新的,去除了“上一次游戏痕迹”的环,这要求对容器的内容做好处理。
void JohnslefCircle::GetCirclre(const int& num)
{
if (num > 0)
{
//有内容
if (m_VecData.size() != 0)
{
//去除内容
m_VecData.clear();
//去除容量
vector(m_VecData).swap(m_VecData);
}
//申请容量
m_VecData.reserve(num);
//初始化每一个位置的值
for (int i = 0; i < num; ++i)
{
m_VecData.push_back(i + 1);
}
}
}
2、筛选出圈
//开始游戏,每out-1个人去掉一个人
void JohnslefCircle::Out(const int& out)
{
if (m_VecData.size() < out)
{
return;
}
int aLive = m_VecData.size();
int count = 0;
vector::iterator itData = m_VecData.begin();
while (aLive != (out - 1))
{
++itData;
++count;
if (itData == m_VecData.end())
{
itData = m_VecData.begin();
}
//已经出局的不算
while (*itData == -1)
{
++itData;
if (itData == m_VecData.end())
{
itData = m_VecData.begin();
}
}
//出局
if (count == out - 1)
{
cout << *itData << "出局" << endl;
*itData = -1;
--aLive;
count = -1;
}
}
}
3、打印剩余
//显示剩余结果
void JohnslefCircle::ShowRes()
{
vector::iterator itData = m_VecData.begin();
while (itData != m_VecData.end())
{
if (*itData != -1)
{
cout << *itData << endl;
}
++itData;
}
}
4、游戏逻辑
//约瑟夫游戏
void JohnslefCircle::JohnselfGame(const int num, const int out)
{
GetCirclre(num);
Out(out);
ShowRes();
}
四、通过对外函数调用约瑟夫游戏
//约瑟夫环游戏
void JohnslefCircle::Game(const int num, const int out)
{
JohnselfGame(num, out);
}
五、完整代码与运行结果:
//约瑟夫环
class JohnslefCircle
{
public:
JohnslefCircle();
//约瑟夫环游戏
void Game(const int num, const int out);
private:
//保存数据信息
vector m_VecData;
//获取指定长度额约瑟夫环
void GetCirclre(const int& num);
//开始游戏,每out-1个人去掉一个人
void Out(const int& out);
//显示剩余结果
void ShowRes();
};
JohnslefCircle::JohnslefCircle():m_VecData()
{
}
void JohnslefCircle::Game(const int num, const int out)
{
GetCirclre(num);
Out(out);
ShowRes();
}
void JohnslefCircle::GetCirclre(const int& num)
{
if (num > 0)
{
//有内容
if (m_VecData.size() != 0)
{
//去除内容
m_VecData.clear();
//去除容量
vector(m_VecData).swap(m_VecData);
}
//申请容量
m_VecData.reserve(num);
//初始化每一个位置的值
for (int i = 0; i < num; ++i)
{
m_VecData.push_back(i + 1);
}
}
}
void JohnslefCircle::Out(const int& out)
{
if (m_VecData.size() < out)
{
return;
}
int aLive = m_VecData.size();
int count = 0;
vector::iterator itData = m_VecData.begin();
while (aLive != (out - 1))
{
++itData;
++count;
if (itData == m_VecData.end())
{
itData = m_VecData.begin();
}
//已经出局的不算
while (*itData == -1)
{
++itData;
if (itData == m_VecData.end())
{
itData = m_VecData.begin();
}
}
//出局
if (count == out - 1)
{
cout << *itData << "出局" << endl;
*itData = -1;
--aLive;
count = -1;
}
}
}
void JohnslefCircle::ShowRes()
{
vector::iterator itData = m_VecData.begin();
while (itData != m_VecData.end())
{
if (*itData != -1)
{
cout << *itData << endl;
}
++itData;
}
}
void func2()
{
JohnslefCircle John;
John.Game(5, 3);
}
void func2()
{
JohnslefCircle John;
John.Game(50, 3);
}



