约瑟夫环Java课程方案大Word格式.docx
《约瑟夫环Java课程方案大Word格式.docx》由会员分享,可在线阅读,更多相关《约瑟夫环Java课程方案大Word格式.docx(15页珍藏版)》请在冰豆网上搜索。
3.详细设计6
3.1类函数解读6
3.2主函数解读8
4.调试分析9
4.1所遇问题9
4.2实验心得10
5.用户使用说明10
5.1每一步操作说明10
6.测试结果11
7.附录:
程序源代码11
1、?
?
【问题描述】
约瑟夫<
Joseph)问题的一种描述是:
编号为1,2,…,n的n个人按顺时针方向围坐一圈,每人持有一个密码<
正整数)。
一开始任选一个正整数作为报数上限值m,从第一个人开始按顺时针方向自1开始顺序报数,报到m时停止报数。
报m的人出列,将他的密码作为新的m值,从他在顺时针方向上的下一个人开始重新从1报数,如此下去,直至所有人全部出列为止。
试设计一个程序求出出列顺序。
【基本要求】
利用单向循环链表存储结构或顺序存储结构模拟此过程,按照出列的顺序印出各人的编号。
【测试数据】
m的初值为20;
n=7,7个人的密码依次为:
3,1,7,2,4,8,4,首先m值为6<
正确的出列顺序应为6,1,4,7,2,3,5)。
<
)
开发工具:
JDK1.6eclipse6.0
运行环境:
WindowsXP及其以上系统
2?
本个实验所输入的值都强制转化为Int数据类型,因为人数一定是个正整数,而每个人所持的密码将会作为下一次循环的步数,所以也一定是一个整数;
初始密码也是步数,所以也是一个正整数。
在输入值的取值范围上,每人的密码是一个大于零的整数,初始密码也是一个大于零的整数,人数同样也是一个正整数。
3、?
1.可以在以下环境中运行本次实验
①在DOS环境中编译“约瑟夫环.Java”文件
②在Eclipse6.0及其以上编译环境下运行
2.根据文字要求依次输入人数、每人密码、初始密码等一些数据<
见图1.3.2)
<
图)1.3.2
4、?
约瑟夫环代码约瑟夫环<
Josephus)问题是由古罗马的史学家约瑟夫<
Josephus)提出的,他参加并记录了公元66—70年犹太人反抗罗马的起义。
约瑟夫作为一个将军,设法守住了裘达伯特城达47天之久,在城市沦陷之后,他和40名死硬的将士在附近的一个洞穴中避难。
在那里,这些叛乱者表决说“要投降毋宁死”。
于是,约瑟夫建议每个人轮流杀死他旁边的人,而这个顺序是由抽签决定的。
约瑟夫有预谋地抓到了最后一签,并且,作为洞穴中的两个幸存者之一,他说服了他原先的牺牲品一起投降了罗马。
本次实验的不同点在于有一个初始密码M、每人又有个密码,在他死后<
出局)之后将作为下一个循环的步数,这样以此类推得出最后一个幸存者。
这个实验主要是模仿约瑟夫环的意思模拟约瑟夫环。
差别在与每人的密码将作为下一个循环步数继续开始另一个约瑟夫环的循环处理。
最后得到一个出此链表的数字下标代号。
5、?
①初始密码M=20
②人数为7
③7个人的密码依次为:
3,1,7,2,4,8,4
最后得到一个出此链表顺序,用每个链表中元素的下标输出数据。
1?
创建Node和LinkList这两个类,在Node类中定义一些函数,为主程序中调用这些函数所服务;
LinkList类Head指针调用SetLink函数,然后遍历结点,一次删除结点,使得指针后移。
在主函数中运用一个For循环作为足要算法,一次实现约瑟夫环的功能。
2、?
先创建了一个linklist对象,然后分别申明inCount和resultIncount这两个私有成员变量。
然后通过inCount=Integer.parseInt(input.readLine(>
>
。
把输入的内容转化成INT类型,赋值给inCount。
通过一个For循环语句作为其主要算法实现。
Nodep=link.head,q=link.last?
inti=0?
//?
intj=0?
for(?
{i++?
if(i==m>
{
i=0?
m=p.getData(>
System.out.print(p.getCount(>
+"
"
link.removeNode(q>
Q?
p=p.getLink(>
//Q结?
j++?
if(j==inCount>
break?
FOR?
continue?
}
q=q.getLink(>
//Q?
p=q.getLink(>
//P?
}
3?
?
classNode{
privateintdata[]=newint[2]?
privateNodelink?
privatestaticintcount=-1?
publicNode(intdata>
this.data[0]=data?
this.data[1]=++count?
link=null?
}
publicvoidsetData(intdata>
publicintgetData(>
returndata[0]?
publicintgetCount(>
returndata[1]?
publicvoidsetLink(Nodelink>
this.link=link?
publicNodegetLink(>
returnlink?
}
在这个结点NODE类中定义了诸如setData、getData、getData、getCount、setLink、getLink等一些函数,为主函数调用这些函数做好准备。
这也是前期工作的准备。
classLinkList{
publicNodehead?
publicNodelast?
publicLinkList(intdata>
head=newNode(data>
//Head?
NODE?
Head
head.setLink(head>
SetLink?
last=head?
publicStringvistAllNode(>
{//?
Nodenext=head?
Strings=newString(>
do{
s=s+next.getData(>
next?
S?
next=next.getLink(>
}while(next!
=head>
returns?
publicbooleanremoveNode(Nodenode>
{//?
node?
if(node==last>
head=head.getLink(>
last.setLink(head>
=?
}elseif(node.getLink(>
==last>
last=node?
//Last?
}else{
NodetempN=node.getLink(>
TEMPN?
tempN=tempN.getLink(>
tempN?
node.setLink(tempN>
//node?
tempN
returntrue?
true
publicbooleanremoveAll(>
{//?
//Head=Head
//Last=Head
head.setData(0>
//head?
publicvoidappend(intdata>
{//此?
Nodetemp=newNode(data>
TEMP?
last.setLink(temp>
last=temp?
在LinkList类中申明头尾指针head和last,head和last分别调用Node和setLink函数,在进行结点的遍历和,当删除一个结点之后便产生了指针后移的问题,直到头尾指针相同。
publicclass?
privatestaticLinkListlink=newLinkList(0>
LinkList?
privatestaticintinCount?
privatestaticintresultInCount?
publicstaticvoidmain(String[]args>
throwsIOException{
intenter?
StringinputString=newString(>
BufferedReaderinput=newBufferedReader(newInputStreamReader(
System.in>
System.out.print("
\n?
(?
:
"
inCount=Integer.parseInt(input.readLine(>
INT?
赋?
给INCOUNT
intm=Integer.parseInt(input.readLine(>
System.out.println("
for(resultInCount=0?
resultInCount<
inCount?
resultInCount++>
inputString=input.readLine(>
enter=Integer.parseInt(inputString>
link.append(enter>
}//?
link.removeNode(link.last>
Nod