大概花了一个晚上搭一个中午的时间,完善了一个关于Josephus的程序,这个Josephus游戏可是非常经典的算法,作为一个想从事软件的人最好能够理解一下,毕竟这个计算机教材上也讲过类似题目,具体的关于问题的描述我就不多说了,这个Josephus一般都是用队列来实现,当然了对于一个具体的算法而言数据结构并不是第一重要的,最重要的还是算法本身。这个程序关键之处还是在于如何巧妙地实现对淘汰的人的处理,用队列比较好实现。

public class CountDown {
   
public static Object josephus(Queue_List q,int k)throws QueueStackEmpty,QueueStackFull{

if(q.isEmpty()) return null;
while(q.size()>1){ 
q.traversal();//遍历所有队列元素 
for(int i=1;i<k;i++){
q.enqueue(q.dequeue()); 
}   
Object e=q.dequeue();
System.out.println("\n孩子"+e+"退出");
System.out.print("\n队头指针指向"+q.getItem(q.f)+"队尾指针指向"+q.getItem(q.r-1)+"\n");
}
return q.dequeue();
}
//将一组对象组织为一个队列
public static Queue_List buildQueue(Object[] a){
Queue_List ql = new Queue_List();    
for(int i=0;i<a.length;i++){
ql.enqueue(a[i]);
}
return ql;
}
public static void main(String[] args) {
 try{ 
String[] kid ={
"Alice","Bob","Cindy","Oliver","July",
"Rikc","Robin","Bill","Tom","Sam","Kim",
"Lin","Linda","UU","Baidu","Web"
};
System.out.println("最终的幸运者是:"+josephus(buildQueue(kid),1));
}catch(QueueStackEmpty e){
System.out.println("栈空了");
}catch(QueueStackFull e){
System.out.println("栈满了");
}
}

}
//模仿队列数据结构的类
class  Queue_List   {
   //队列的元素仍不能超过SIZE个元素,超过部分就会回到下标为0处,是否覆盖原来的数据取决于队头指针的值
    public final int SIZE = 17;
public Object[] Q;
    int f,r; //分别指向队头元素和队尾元素
public Queue_List(){
Q = new Object[SIZE];
f = -1; //队头指针初始化为-1;
}
public Queue_List(int num){
   Q= new Object[num];
   f = -1; //队头指针初始化为-1;
}
//返回指定元素的下标值
public int getElement(Object obj){
for(int i=0;i<r;i++){
if(Q[i].equals(obj))return i;
}
return -2;
}
//返回指定下标处的值
public Object  getItem(int index){
return Q[index];
}
//替换或设置指定下标处的值
public void setItem(int index,Object obj){
Q[index]=obj;
}
//弹出队头元素
public Object dequeue(){
       if(isEmpty())
       throw  new QueueStackEmpty("栈为空");
int i=f; 
f++; //队头指针往后移动一位
       return Q[i];
    }
//添加元素到队列中,添加成功返回true
public boolean enqueue(Object obj)throws QueueStackFull{
if(f == -1){  f=0;r=0; }
if(r>=(SIZE)){ //如果队尾指针已经到达尾部 
if(f==0){
throw new QueueStackFull("栈满了"); 

int tempF=f,tempSize=size();
for(int i=0,j=tempF;i<tempSize;i++,j++){
Q[i]=Q[j];
}
//重新定位队头指针和队尾指针
f=0;r=tempSize; 
}    
    Q[r]=obj;
    r++;    //队尾指针总是指向最后一个将要添加的元素  
    return true; 
    }
 
public int size() {   
return  (r-f);
}
 
public boolean isEmpty() {
   if(size()==0 || f== -1)
   return true;
return false;
}
public void traversal(){ 
int j=0;   
for(int i=f;i<r;i++){
  j++;
  if(j%10==0)
  System.out.println();
  System.out.print("  "+ Q[i]);
  }  
}
}

一个非常有趣的算法程序(有趣只针对程序猿)就是Josephus问题的更多相关文章

  1. 转一个csdn看到的帖子:而立之年的程序猿失业了 [问题点数:0分,结帖人jinxingfeng_cn]

    http://bbs.csdn.net/topics/390612263?page=1#post-395768948

  2. 一个net程序猿必备工具

    自古以来,人类的进步都是依赖于工具的进步,从刀耕火种,到使用青铜器,再到现在的科技,每一次都使我们的工作效率提高了无数倍,所以一个好的工具能使我们提高无数倍的工作效率,下面,我就根据自己简单的总结一下 ...

  3. 新建一个DataTable(只针对一列)

    /// <summary> /// 新建一个DataTable(只针对一列) /// </summary> /// <param name="dataStr&q ...

  4. 关于只针对ie7浏览器的css问题

    如代码: .centerDiv .search_k2{ margin-left: 18px; *margin-left: 9px; margin-top: 10px; height: 40px;} 中 ...

  5. WaitForSingleObject与WaitForMultipleObjects用法详解(好用,而且进入一个非常高效沉睡状态,只占用极少的CPU时间片)

    在多线程下面,有时候会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects ...

  6. 面试王牌 JAVA 多态只针对方法 不针对属性

    子类是永远继承父类的非私有化方法,当子类中重写父类方法时,调用的是子类的方法,没有重写时,调用的是父类中的方法 1 多态是只针对方法,而不是属性的,但是写法上,子类重写父类的属性,编译器是不会报错的 ...

  7. 想让一个Widget成为模态,我们只需要对其设置setAttribute(Qt::WA_ShowModal, true);

    想让一个Widget成为模态,我们只需要对其设置: setAttribute(Qt::WA_ShowModal, true); 注意:这是QWidget的成员函数 ,也就是说,QWidget可以显示为 ...

  8. 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截

    程序猿修仙之路--数据结构之你是否真的懂数组?   数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构  .要想在之后的江湖历练中通关,数据结构必不可少. ...

  9. 每一个程序猿必知之SEO

    似乎由于受这篇文章的影响 http://katemats.com/what-every-programmer-should-know-about-seo/ 于是我也觉得我应该写一个每一个程序猿必知之S ...

随机推荐

  1. WearableListView的使用和一些思考

    今年加盟了一家做手表的公司,至此开启了androidwear(类)的开发之门. 近日要做一个手表上的List显示,为此也是花了很多的心思在List效果上,多日下来,有些心得. 一.需求确定: 手表上的 ...

  2. iOS GorupBy

    转自:  IOS 数组分组 Grouped NSArray 1 2 3 4 5 6 7 8 NSMutableSet *set=[NSMutableSet set];   [_list enumera ...

  3. C#设置IP地址,启用禁用适配器

    界面效果图如下: 报表界面 说下关键代码 需要开启 Windows Management Instrumentation服务(默认已经开启),在程序中需要增加 Management引用. 主要有Net ...

  4. 02C#基础(1)

    1.关键字 C#中定义了很多关键字,关键字是构成C#基本语法的,不用去背,用的多就记住了 2.标识符 标识符是用来给类.方法.变量等命名的 命名规则:  (1)由字母.中文(不推荐).数字.下划线组成 ...

  5. C++ 性能剖析 (四):Inheritance 对性能的影响

    (这个editor今天有毛病,把我的format全搞乱了,抱歉!) Inheritance 是OOP 的一个重要特征.虽然业界有许多同行不喜欢inheritance,但是正确地使用inheritanc ...

  6. 跟我学android-Notification

    Notification 可以理解为通知的意思,会出现在通知栏,比如来了一条短信 使用 Notification 有以下3个步骤: 1. 创建 NotificationManager的对象 2.为No ...

  7. nginx配置无效的问题

    今天修改nginx的一个配置文件,却怎么都没效果,发现是启动nginx指定的配置文件不一样. #ps aux|grep nginx root     17672  0.0  0.0  45856  2 ...

  8. Hibernate4 clob字段存取

    domain的字段: private Clob content; hibernate的xml映射 <property name="content" type="cl ...

  9. PHP程序异常处理实现方法

    一个异常(Exception)则是在一个程序执行过程中出现一个例外或是一个事件,它中断了指令的运行,跳转到其他程序模块继续执行.所以异常处理经常被当作程序的控制流程使用.无论是错误还是异常,应用程序都 ...

  10. 2015 偶数求和 AC 杭电

    偶数求和 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submi ...