约瑟夫问题是数据结构与算法里的经典问题。我用C++数组写了个解答,并且加入了异常处理,来保证程序的正确性和健壮性。本人能力较差,让诸位大牛见笑了,请多多指教!
问题描述:设n个人围坐在一个圆桌周围,现在从s个人开始报数,数到第m个人,让他出局;然后从出局的下一个人重新报数,数到第m个人,再让他出局,……,如此反复直到所有的人全部出局为止。下面要解决的Josephus问题是:对于任意给定的n,s和m,求出着n个人的出局序列。请以n=9,s=1,m=5为例,人工模拟Josephus的求解工程以求得问题的解。
Josephus.h
#ifndef JOSEPHUS_H
#define JOSEPHUS_H
class Josephus
{
public:
Josephus(int n = 9, int s = 1, int m = 5);
int get();
~Josephus();
private:
int* a;
int m_n; //有m_n个人围坐在一起
int m_s; //从第m_s个人开始报数
int m_m; //数到第m_m个人让他出局
};
#endif
Josephus.cpp
#include "Josephus.h"
#include <iostream>
using namespace std;
Josephus::Josephus(int n, int s, int m)
{
m_n = n;
m_s = s - 1;
if(m <= 0) //如果m的值小于等于,则抛出异常
throw logic_error("m的值不能小于0");
m_m = m;
a = new int[m_n];
if(a == 0) //如果内存未分配则抛出异常
{
throw bad_alloc("内存分配错误");
}
//初始化数组元素
for(int i = 0; i < m_n; i++)
{
a[i] = i + 1;
cout << a[i] << endl;
}
}
int Josephus::get()
{
int i = 0;
//将成员变量用临时变量保存
int n = m_n;
int j = m_s;
while(1)
{
if(a[j] != -1)
{
i++;
if(i == m_m)
{
i = 0;
a[j] = -1;
n--;
}
}
j++;
if(j == m_n)
{
j = 0;
}
if(n == 1)
break;
}
for(int h = 0; h < m_n; h++)
{
if(a[h] != -1)
return a[h];
}
return -1;
}
Josephus::~Josephus()
{
delete [] a;
}
测试代码
#include "Josephus.h"
#include <iostream>
using namespace std;
int main()
{
try
{
Josephus j;
cout << "剩下的人是:" << j.get() << endl;
}
catch(const logic_error& le)
{
cerr << le.what() << endl;
}
catch(const bad_alloc& ba)
{
cerr << ba.what() << endl;
}
system("pause");
return 0;
}
输出结果为8
如果改成
try
{
Josephus j(9,1,0);
cout << "剩下的人是:" << j.get() << endl;
}
catch(const logic_error& le)
{
cerr << le.what() << endl;
}
catch(const bad_alloc& ba)
{
cerr << ba.what() << endl;
}
输出结果为
m的值不能小于0
免责声明:内容和图片源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。