H面试程序(2)josephus 问题

       josephus问题其实就是一个游戏,一群小孩围成一个圈,设置一个数,这个数是个小于小孩总数大于0的一个整数,从第一个小孩开始报数,当其中一个小孩报到你设置的那个数的时候离开那个圈,这样一来反复报下去,直到只剩下最后一个小孩的时候那个小孩就是胜利者,写程序来找出这个小孩 
 

      

 class Josephus  
 {  
 public:  
	 Josephus(int numofInput=10,int intervalofInput=1)  
	 {  
		 num = numofInput;  
		 interval = intervalofInput;  
	 }  
	 void initial();  
 protected:  
	 int num;  
	 int interval;  
 }; 

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

 void Josephus::initial()  
 {  
	 int num,interval;  
	 cout<<"请输入孩子总数:";  
	 cin>>num;  
	 if(num<2)  
	 {  
		 cout<<"孩子总数不能小于2,否则不能构成环链!";  
		 return;  
	 }  
	 cout<<"请输入抽选号码";  
	 cin>>interval;  
	 if(interval<1|interval>num)  
	 {  
		 cout<<"请输入抽选号码不能小于1或者大于小孩总数!";  
		 return;  
	 }  
	 Josephus::num=num;  
	 Josephus::interval=interval;  
	 Ring a(num);  
	 a.ShowRing(num);  
	 cout<<endl;    //前面算是一个初始化的工作
	 for(int i=1;i<num;i++)  //这边才是开始做游戏,要做num - 1次才能得出最后结果
	 {  
		 a.CountInterval(interval);  //开始数数
		 a.ShowWiner_loser();   //看是那个小孩要被剔除
		 a.OutChild();   //将出去的小孩剔除
	 }  
	 cout<<endl<<"胜利者是:";  
	 a.ShowWiner_loser();  
 }

struct Children  
 {  
	 int number;  
	 Children *next;  
 };  

 class Ring  
 {  
 public:  
	 Ring(int num)  
	 {  
		 josephus = new Children[num];  //josephus保存数组的首元素首地址
		 point = josephus;  
		 for(int i=1;i<=num;i++)  
		 {  
			 point->number = i;    //从1到num对数组进行标号
			 point->next = josephus + i % num;  
			 point=point->next;  
		 }  
		 point = &josephus[num-1];  //point指向最后一个小孩
	 }  
	 ~Ring()  
	 {  
		 delete[] josephus;  
	 }  
	 void ShowRing(int num);  
	 void CountInterval(int interval);  
	 void OutChild();  
	 void ShowWiner_loser();  
 protected:  
	 Children *josephus;  
	 Children *point;  
	 Children *cut_point;  
 }; 


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

using namespace std;  
void Ring::ShowRing(int num)  
{  
	point=josephus;//也可以写成point=point->next;但前着效率高一点点  
	for(int i=1;i<=num;i++)  
	{  
		cout<<point->number<<",";  
		point=point->next;  
	}  
	point=&josephus[num-1];//输出过后恢复point应该在的位置  
}  
void Ring::CountInterval(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::ShowWiner_loser()  
{  
	cout<<point->number<<",";  
} 


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

 void main()  
 {  
	 Josephus a;  
	 a.initial();  

 } 



  
//程序作者:管宁  
//站点:www.cndev-lab.com  




你可能感兴趣的:(H面试程序(2)josephus 问题)