约瑟夫问题(丢手帕问题)
/**
?*?作者:徐守威
?*?功能:約瑟夫問題(丟手帕問題)
?*?具體問題:設編號為1,2,3....n的n個人圍坐一圈,約定編號為k(1<=k<=n)的人從1開始
?*?報數,數到m的那個人出列,它的下一位從一開始報數,報到m的那個人又出列,以此類推,
?*?直到所有人出列為止,如此產生一個出列編號的序列...
?*?解決方案:鏈表
?*/
package?com.jasxu;
import?java.io.*;
public?class?T4?{
?
/**
?*?@param?args
?*/
public?static?void?main(String[]?args){
//?TODO?Auto-generated?method?stub
try
{
InputStreamReader?isr=new?InputStreamReader(System.in);
BufferedReader?br=new?BufferedReader(isr);
System.out.println("請輸入參加該游戲小孩的個數:");
String?joinNmu=br.readLine();
System.out.println("請輸入您想從編號為幾的小孩開始報數?");
String?n1=br.readLine();
System.out.println("請輸入您想數到幾的小孩出列?");
String?n2=br.readLine();
int?num1=Integer.parseInt(n1);
int?num2=Integer.parseInt(n2);
int?joinLen=Integer.parseInt(joinNmu);
CycLink?cyclink=new?CycLink();
cyclink.setLen(joinLen);
cyclink.createLink();
cyclink.setK(num2);
cyclink.setM(2);
cyclink.show();
cyclink.play();
}
catch(Exception?e)
{
e.printStackTrace();
}
?
}
}
?
//構建各個孩子
class?Child
{
//定義child的編號
int?no;
//定義可以指向下一個的指針
?
Child?nextChild=null;
//創(chuàng)建構造函數
public?Child(int?no)
{
//賦編號
this.no=no;
}
}
//構建一個環(huán)形鏈表
class?CycLink
{
//先定義一個指向鏈表第一個小孩的引用
//指向第一個小孩的引用,不能動
Child?firstChild=null;
//定義一個游標,相當于跑龍?zhí)?/span>
Child?temp=null;
//定義一個表示大小的的len,表示共有幾個小孩
int?len=0;
int?k=0;
int?m=0;
//構造函數,用來設置環(huán)形鏈表的大小
public?void?setLen(int?len)
{
this.len=len;
}
//設置m的值
public?void?setM(int?m)
{
this.m=m;
}
//設置從第幾個人開始數數
public?void?setK(int?k)
{
this.k=k;
}
//游戲實現
public?void?play()
{
//設置跑龍?zhí)椎男『?/span>
Child?temp=this.firstChild;
//1.找到開始數數的人
for(int?i=1;i<k;i++)
{
temp=temp.nextChild;
}
while(this.len!=1)
{
//2.數m下
for(int?j=1;j<m;j++)
{
temp=temp.nextChild;
}
//3.找到要出圈的前一個小孩
//定義一個2號跑龍?zhí)椎娜?/span>
Child?temp2=temp;
while(temp2.nextChild!=temp)
{
temp2=temp2.nextChild;
}
//4.數完了過后將數到m的小孩退出圈
temp2.nextChild=temp.nextChild;
//讓temp指向下一個數數的小孩
temp=temp.nextChild;
this.len--;
}
//輸出最后一個小孩
System.out.println("最后出圈的小孩是:"+temp.no+"號小孩!");
}
?
//初始化環(huán)形鏈表
public?void?createLink()
{
//統計有多少個孩子
for(int?i=1;i<=len;i++)
{
if(i==1)
{
//首先創(chuàng)建第一個小孩
Child?ch=new?Child(i);
//將第一個孩子的應用交給firstChild
this.firstChild=ch;
//同時也要將引用交給跑龍?zhí)子?/span>
this.temp=ch;
}
else
{
//判斷是否是創(chuàng)建最后一個小孩
if(i==len)
{
//繼續(xù)創(chuàng)建小孩
Child?ch=new?Child(i);
//將temp的指針指向下一條地址的引用
temp.nextChild=ch;//這條線相當于搭橋的線
//橋答完后還要讓temp指向剛剛創(chuàng)建的那個孩子
temp=ch;
//最后一個小孩的指針應指向頭一個地址的引用
temp.nextChild=this.firstChild;
}
else
{
//繼續(xù)創(chuàng)建小孩
Child?ch=new?Child(i);
//將temp的指針指向下一條地址的引用
temp.nextChild=ch;//這條線相當于搭橋的線
//橋答完后還要讓temp指向剛剛創(chuàng)建的那個孩子
temp=ch;
}
?
}
}
}
//打印該環(huán)形鏈表
public?void?show()
{
//定義一個跑龍?zhí)?/span>
Child?temp=this.firstChild;
do
{
System.out.print(temp.no+"?");
temp=temp.nextChild;
}while(temp!=this.firstChild);
}
}
?
轉載于:https://www.cnblogs.com/Jasxu/p/3529753.html
總結
以上是生活随笔為你收集整理的约瑟夫问题(丢手帕问题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Transaction And Lock
- 下一篇: linux内核学习之三:linux中的3