josephus问题用面向对象的方法来实现

还是josephus问题,今天又学习了用面向对象的方法来解决这个问题。

面向对象的程序设计是由类组合而成的,有类则必然有对象,程序之间的交互主要是通过对象与对象之间的关系进行操作的。
思路:
1.我们把josephus问题分解成了josephus类和ring类,在主函数中,用户只需要使用josephus类设计其对象,明确知道josephus类的外部接口函数也就是initial()就可以了。
2.至于josephus的内部实现又是如何与Ring类进行操作的,使用者一概不需要知道,只需要拿来用。也就是只需要知道接口和接口函数就可以了。
3.这种程序设计的方法很好的熬糊了各类成员数据的安全,主函数代码调用极其简单,只有建立对象和调用对象方法的操作这两部。
4.以后类一旦要修改,只修改类体本身就可以,而主函数不需要做任何修改。就相当于一个手机,用户不需要知道里面具体实现的原理,只要会用就可以了。

程序:
首先是ring:它是一个环链的类,他的方法主要是还里面的操作 ,比如输出环,比如报数,还有剔除被点到的人。它有几个成员变量,都是指针。它跟josephus的交互的主要在于那几个函数的num和s参数。
ring.h
struct Children
{
int number;
Children*next;
};
class Ring
{
public:
Ring(int num,int s)
{
josephus=new Children[num];
Children*point=josephus;
for(int i=1;i<=num;i++)
{
point->number=i;
point->next=josephus+i%num;
point=point->next;
}
if(s==1)
point=&josephus[num-1];
else
point=&josephus[s-2];
}
~Ring()
{
delete[]josephus;
}
void showRing(int num,int s);
void coutInterval(int interval);
void OutChild();
void ShowWinner();


protected:
Children *josephus;
Children*point;
Children*cut_point;
};

ring.cpp
#include<iostream>
#include"ring.h"
using namespace std;


void Ring::showRing(int num,int s)
{
point=josephus;
for(int i=0;i<num;i++)
{
cout<<point->number<<",";
point=point->next;
}
if(s==1)
point=&josephus[num-1];
else
point=&josephus[s-2];
}


void Ring::coutInterval(int interval)
{
for(int i=0;i<interval;i++)
{
 cut_point=point;
 point=cut_point->next;
}
}


void Ring::OutChild()
{
cut_point->next=point->next;
point=cut_point;
}


void Ring::ShowWinner()
{
cout<<"获胜者的号码是:"<<point->number<<endl;
}

下面是josephus类:可以看出它主要是提供输入和验证三个参数的作用,三个参数num,s,interval。就好像josephus是一个长官,它负责制定规则,而ring是它的下属,他负责把这件事(找出幸存者)做出来。这就是面向对象的神奇之处 ,各个类都有明确的分工。

josephus.h
class Josephus
{
public:
Josephus(int num=10,int s=1, int interval=1)
{
Josephus::num=num;
Josephus::s=s;
Josephus::interval=interval;
}
void initial();
protected:
int num;
int s;
int interval;
};

josephus.cpp
#include <iostream>
#include"josephus.h"
#include"ring.h"


using namespace std;
void Josephus::initial()
{
int num,s,interval;
cout<<"输入学生人数:";
cin>>num;
if(num<2)
{
cout<<"人数必须大于1";
return;
}
cout<<endl<<"请输入从第几个学生开始数起:";
cin>>s;
if(s>num)
{
cout<<"开始报数的序号必须小于总人数";
return;
}
cout<<endl<<"请输入抽选人数:";
cin>>interval;
if(interval<1|interval>num)
{
cout<<"请重新输入在1到总数之间的数";
return;
}


/*Josephus::num=num;
Josephus::s=s;
Josephus::interval=interval;*/


Ring a(num,s);
a.showRing(num,s);
for(int i=1;i<num;i++)
{
a.coutInterval(interval);
a.OutChild();

cout<<"胜利者是:";
a.ShowWinner();




}

接下来是主程序部分:很简单,因为它的工作只是负责发一声命令就好了。
test.cpp
#include<iostream>
#include"josephus.h"
using namespace std;

void main()
{
        Josephus a;
a.initial();
cin.get();
cin.get();
}
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值