约瑟夫问题面向对象C++版程序设计报告.docx

上传人:b****1 文档编号:15114461 上传时间:2023-06-30 格式:DOCX 页数:26 大小:98.99KB
下载 相关 举报
约瑟夫问题面向对象C++版程序设计报告.docx_第1页
第1页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第2页
第2页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第3页
第3页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第4页
第4页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第5页
第5页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第6页
第6页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第7页
第7页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第8页
第8页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第9页
第9页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第10页
第10页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第11页
第11页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第12页
第12页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第13页
第13页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第14页
第14页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第15页
第15页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第16页
第16页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第17页
第17页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第18页
第18页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第19页
第19页 / 共26页
约瑟夫问题面向对象C++版程序设计报告.docx_第20页
第20页 / 共26页
亲,该文档总共26页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

约瑟夫问题面向对象C++版程序设计报告.docx

《约瑟夫问题面向对象C++版程序设计报告.docx》由会员分享,可在线阅读,更多相关《约瑟夫问题面向对象C++版程序设计报告.docx(26页珍藏版)》请在冰点文库上搜索。

约瑟夫问题面向对象C++版程序设计报告.docx

约瑟夫问题面向对象C++版程序设计报告

学院

班级

学号

姓名

摘要

本作业解决Josephus问题的求解,以及Josephus问题的扩展的求解。

Josephus问题的描述如下:

n个小孩围成圈做游戏,游戏将决定出一个胜利者(Josephus问题扩展则可以求出多个获胜者)。

假定一个数m,从第s个小孩起,顺时针计数,每次数到第m个小孩,该小孩离开,接着又从下一个小孩开始数,数到第m个小孩,该小孩也离开,如此不断反复进行,最后剩下的一个(多个)小孩为胜利者。

对于给定的n、m和s,找出最后的胜利者。

Josephus问题的扩展则是在原来Josephus问题基础上增加了“获胜者个数”这一限制。

在本作业中Josephus问题的解决主要是基于对象的解决方案(Object-BasedSolution),其中涉及到BoyRing类和Jose类。

主要实现方式则是环链表,这使得Josephus问题得到一个比较满意的解决。

本作业的程序设计达到了要求,实现的方式相对较好。

最终得到的结果设计者比较满意。

1摘要

1.1设计题目

Josephus问题(JosephusProblem)及其扩展

1.2设计内容

利用循环链表运用面向对象的设计方案实现Josephus问题的求解。

Josephus问题如下:

n个小孩围成圈做游戏,游戏将决定出一个胜利者。

假定一个数m,从第s个小孩起,顺时针计数,每次数到第m个小孩,该小孩离开,接着又从下一个小孩开始数,数到第m个小孩,该小孩也离开,如此不断反复进行,最后剩下的一个小孩为胜利者。

对于给定的n、m和s,找出最后的胜利者。

其中n、m和s都为正整数,切有n>1,1<=m<=n和1<=s<=n的关系。

程序扩展是在Josephus问题的基础上,由原来的1个获胜者扩展到m个胜利者,其实现的方式和Josephus问题的实现基本相同。

其中n、m、s的要求和Josephus问题的完全相同,新增的1<=w<=n。

1.3开发工具

主要用到的开发工具为:

DevC++5.0和Win32。

1.4应用平台

Windows2000/XP/Vista32位

2详细设计

2.1程序结构

改程序分成三个抽象层次,第一层是应用层,直接指使Jose类对象去完成求解工作;第二层是Jose类层,描述Josephus问题的求解细节;第三层是BoyRing类层,辅助Jose类完成求解过程(上述三层间的关系描述如图J-1,这也是程序模块间的关系)。

图J-1.对象实现中程序模块的相互关系

如图J-1所示,main函数用到了Jose类,Jose类又用到了BoyRing类。

整个程序的实现流程如图J-2。

程序中类:

BoyRing类和Jose类

BoyRing类中的数据成员有:

Boy*pBegin,*pivot,*pCurrent三个指针,分别为起始位置的指针,哨兵指针,被切掉位置指针。

BoyRing类中的成员函数分别为:

函数

相关说明

BoyRing(intn);

构造函数。

参数为int类型的n,主要完成空间申请,构造链表,初始化个参数。

VoidcountBy(intm);

用循环的方式数m个小孩,参数为int类型的m

intgetNum()const;

为一个const函数,返回小孩的编号,无参数

voiddisengage();

利用指针实现小孩离队,无参数

voidprintAll()const;

以特定的格式输出小孩的编号,无参数。

本函数在在本程序中没有起任何作用可以去除。

~BoyRing();

析构函数。

释放申请空间,无参数

图J-2.Josephus问题整体程序流程图

Jose类中的数据成员有:

intn,m,s三个int类型的数,分别表示小孩的总数、间隔数、开始数的小孩编号。

Jose类中的成员函数分别为:

函数

相关说明

Jose(intboys,intinterval,intbegin=1);

构造函数,主要功能初始化各个参数,校验输出的m、n、s参数为intboys,intinterval,intbegin=1

voidgetWinner()const;

求胜利者函数,实例化BoyRing类,以特定的格式输出离队小孩的编号和获胜小孩的编号,无参数

主要函数:

BoyRing:

:

BoyRing(intn);

{

if(n<2)throwexception();

pBegin=newBoy[n];

for(inti=1;i<=n;i++)

{

pBegin[i-1].next=&pBegin[i%n];

pBegin[i-1].code=i;

}

pivot=pCurrent=&pBegin[n-1];

}

//图J-3为流程图

图J-3.BoyRing:

:

BoyRing(intn)函数流程图

voidBoyRing:

:

countBy(intm)

{

for(inti=1;i<=m;++i)

{

pivot=pCurrent;

pCurrent=pCurrent->next;

//挪到下一个小孩的位置

}

}

//图J-4为流程图

图J-4.voidBoyRing:

:

countBy(intm)函数流程图

voidJose:

:

getWinner()

const{

cout<<"Thereare"<

\n";//输出小孩总个数

BoyRingx(n);//创建环状链表(Boying类对象实例化x)

x.countBy(s-1);//转到开始位置

for(inti=1,numinLine=0;i

{

x.countBy(m);

cout<<""<

"":

"\n");

x.disengage();

}

cout<<"\nthewinneris\n"<

}

函数之间的参数传递:

1.由主函数依次输入n、m、s三个数的值;

2.主函数调用Jose:

:

getWinner()函数将n、m、s的值传递到Jose类;同时,Jose类的内部函数Jose:

:

Jose(intboys,intinterval,intbegin=1)得到传入的参数n、m、s,并对三个数的值进行校验;

3.在voidJose:

:

getWinner()const函数将n、m、s三个参数通过将BoyRing类实例化成对象实例x,调用x.countBy()函数出入到类BoyRing中。

4.传入BoyRing类中的各个带参数的函数。

2.2主要功能

Josephus问题程序的主要功能是:

通过外界输入3个或(4个)相关参数,在Josephus问题程序成后输出Josephus的的相关结果。

利用循环链表实现Josephus的求解。

Josephus问题如下:

n个小孩围成圈做游戏,游戏将决定出一个胜利者。

假定一个数m,从第s个小孩起,顺时针计数,每次数到第m个小孩,该小孩离开,接着又从下一个小孩开始数,数到第m个小孩,该小孩也离开,如此不断反复进行,最后剩下的一个小孩为胜利者。

对于给定的n、m和s,找出最后的胜利者。

其中n、m和s都为正整数,切有n>1,1<=m<=n和1<=s<=n的关系。

Josephus问题主要是利用环链表、指针转向。

其实现如图J-5:

图J-5.Josephus问题中的环链表

算法

Jose类{

内部数据成员

小孩总数n

开始位置s

计数间隔m

界面

构造函数

求获胜者者函数

}

其中,Jose类界面具有的具体操作描述为:

构造函数

小孩总数校验

开始位置校验

计数间隔数校验

求获胜者函数

输出求解开始,小孩总数

创建环链表(BoyRing类对象)

转到链表开始位置

while(小孩多于1个(w个))

数m个小孩

小孩输出

小孩离队

endwhile

输出获胜者

在Jose类用到了BoyRing类,其设计如下:

BoyRing类{

内部数据成员

小孩结构指针

当前小孩指针

小孩哨兵指针

界面

构造函数

析构函数

数m个小孩

小孩离队

返回当前小孩编号

输出所有小孩

}

其中,BoyRing类界面的具体操作描述为:

构造函数

按小孩的个数申请空间

初始化环状结构,为小孩编号

指针初始化

析构函数

释放申请空间

数m个小孩函数

for(m间隔)

挪到下一个小孩的位置

endfor

小孩离队函数

哨兵指向的小孩指向当前小孩的的下一个小孩

当前小孩指针赋值与哨兵指针

返回当前小孩的编号

返回当前小孩指针指向的小孩编号

输出所以小孩

按特定的格式输出环中所有小孩的编号

2.3算法实现

//=====================================

//boyring.h

//=====================================

#ifndefHEADER_BOYRING

#defineHEADER_BOYRING

structBoy

{

intcode;

Boy*next;

};

//-----------------------------------

classBoyRing

{

Boy*pBegin,*pivot,*pCurrent;

public:

BoyRing(intn);

voidcountBy(intm);

intgetNum()const;

voiddisengage();

voidprintAll()const;

~BoyRing();

};

//===================================

#endif//HEADER_BOYRING

//=====================================

//boyring.cpp

//=====================================

#include"boyring.h"

#include

usingnamespacestd;

//-------------------------------------

//构造函数

//-------------------------------------

BoyRing:

:

BoyRing(intn)

{

if(n<2)throwexception();//发生错误时自动跳出

pBegin=newBoy[n];//申请一个新的Boy空间,pBegin指向该空间的开始处

for(inti=1;i<=n;i++)

{

pBegin[i-1].next=&pBegin[i%n];//形成链表

pBegin[i-1].code=i;//给孩子孩子编号

}

pivot=pCurrent=&pBegin[n-1];//各指针初始化

}

//------------------------------------

//数m个小孩

//------------------------------------

voidBoyRing:

:

countBy(intm)

{

for(inti=1;i<=m;++i)

{

pivot=pCurrent;

pCurrent=pCurrent->next;//挪到下一个小孩的位置

}

}

//------------------------------------

//返回当前小孩编号

//------------------------------------

intBoyRing:

:

getNum()

const{

returnpCurrent->code;

}

//------------------------------------

//小孩离队

//------------------------------------

voidBoyRing:

:

disengage()

{

pivot->next=pCurrent->next;//哨兵指针指向的小孩指向当前小孩的下一个小孩

pCurrent=pivot;//当前小孩指针等于哨兵指针

}

//------------------------------------

//输出所有小孩编号

//-------------------------------------

voidBoyRing:

:

printAll()const

{

intnuminLine=0;

Boy*p=pCurrent;

do

{

cout<<""<code;

if(!

(++numinLine%10))cout<<"\n";//每一行输出10个

p=p->next;

}

while(p!

=pCurrent);

cout<<"\n";

}

//------------------------------------

//析构函数

//------------------------------------

BoyRing:

:

~BoyRing(){

delete[]pBegin;//释放申请空间

}

//------------------------------------

//=====================================

//jose.h

//=====================================

#ifndefHEADER_JOSE

#defineHEADER_JOSE

classJose{

protected:

intn,m,s;

public:

Jose(intboys,intinterval,intbegin=1);

voidgetWinner()const;

};//===================================

#endif//HEADER_JOSE

//=====================================

//jose.cpp

//=====================================

#include"boyring.h"

#include"jose.h"

#include

usingnamespacestd;

//-------------------------------------

//构造函数

//-------------------------------------

Jose:

:

Jose(intboys,intinterval,intbegin):

n(boys),m(interval),s(begin)

{

if(n<2||m<1||m>=n||s<1||s>=n)//校验n、m、s

{

cerr<<"dataerror.\n";

throwexception();//出现错误跳出

}

}

//------------------------------------

//求获胜者

//------------------------------------

voidJose:

:

getWinner()const

{

cout<<"Thereare"<

\n";//输出小孩总个数

BoyRingx(n);//创建环状链表(Boying类对象实例化x)

x.countBy(s-1);//转到开始位置

for(inti=1,numinLine=0;i

{

x.countBy(m);

cout<<""<

"":

"\n");

x.disengage();

}

cout<<"\nthewinneris\n"<

}

//------------------------------------

//=====================================

//main.cpp

//JosephusProblemObject-basedSolving

//=====================================

#include

#include"jose.h"

usingnamespacestd;

//-------------------------------------

intmain(){

cout<<"请依次输入孩子的个数/间隔人数/开始编号:

\n";

intn,m,s;

cin>>n>>m>>s;

Jose(n,m).getWinner();

Jose(n,m,s).getWinner();

}

//====================================

2.4开发日志

推进时间

主要事务

2011年01月01日

问题分析,流程设计,确定项目中各个类,找出各类的之间的联系以及类内部的各个成员。

2011年01月02日

根据分析所得设计实现算法,编写代码,编译、调试程序。

2011年01月03日

项目完成,进行总结。

3程序调试及运行

3.1程序运行结果

Josephus的执行结果

Josephus问题程序执行后输出的结果。

由键盘依次输入小孩总数10、间隔人数3、开始编号3;

程序执行后输出两个结果,第一个结果是Jose(n,m).getWinner()的执行结果,由于在只有n、m两个参数是,其第三个参数默认值设定为1,所以,其结果执行为:

Thereare10boys。

Boyleavedinorder:

3692718510

thewinneris4

第二个结果是Jose(n,m,s).getWinner()的执行结果,由于这一3个参数完全,所以,其执行结果为:

Thereare10boys。

Boyleavedinorder:

5814931072

thewinneris6

Josephus的扩展程序执行结果

Josephus问题扩展程序执行后输出的结果。

由键盘依次输入小孩总数10、间隔人数3、开始编号3;

程序执行后输出三个结果,第一个结果是Jose(n,m).getWinner()的执行结果,由于在只有n、m两个参数是,其第三个参数默认值设定为1,所以,其结果执行为:

Thereare10boys。

Boyleavedinorder:

3692718510

thewinneris4

第二个结果是Jose(n,m,s).getWinner()的执行结果,由于这一3个参数完全,所以,其执行结果为:

Thereare10boys。

Boyleavedinorder:

5814931072

thewinneris6

第三个结果是Jose(n,m,s,w).getWinner()的执行结果,由于这次多了一个获胜者人数的参数3,所以,其执行结果为:

Thereare10boys。

Boyleavedinorder:

57149310

winners726

3.2程序使用说明

本程序在使用要注意:

1.输入参数时要注意数据的格式为正整数;

2.输入参数的个数Josephus为3(Josephus问题的扩展为4个);

3.输入个参数之间的关系,小孩总数大于等1个;开始位置要大于等于1且小于等小孩总数;计数间隔要大于1且小于小孩总数。

3.3程序开发总结

通过这个学期对面向对象的程序设计的学习,使我本人理解了面向对象的重要性及实用性,同时也锻炼了我们自主学习、查阅资料等方面的能量。

本次程序设计虽然是书上的原程序,整个作业的完成有没有花很多的时间,但我从作业的完成过程中学到了很多东西,它使我明白了独立思考的重要性,动手实践的重要性,看懂了,不代表理解了,会做了。

亲自对手才能发现问题,才知道想办法去解决,而不是理所当然的认为是什么样的。

同时,它也磨练了我们的意志,开发了我们的大脑。

使我们明白什么“叫吃得苦中苦,方为人上人”;明白了成功需要怎样做。

它也教会了我们怎样学习,怎样生活,怎么面对将来的路。

4附件(源程序)

//=====================================

//boyring.h

//=====================================

#ifndefHEADER_BOYRING

#defineHEADER_BOYRING

#include

usingnamespacestd;

//------------------------------------

structBoy

{

intcode;

Boy*next;

};

//-----------------------------------

classBoyRing

{

private:

Boy*pBegin,*pivot,*pCurrent;

public:

BoyRing(intn);

voidcountBy(intm);

intgetNum()const;

voiddisengage();

voidprintAll()const;

~BoyRing();

};

//===================================

#endif//HEADER_BOYRING

//-------------------------------------

//构造函数

//-------------------------------------

BoyRing:

:

BoyRing(intn)

{

if(n<2)throwexcep

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2