一个非常有趣的算法程序(有趣只针对程序猿)就是Josephus问题
大概花了一个晚上搭一个中午的时间,完善了一个关于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问题的更多相关文章
- 转一个csdn看到的帖子:而立之年的程序猿失业了 [问题点数:0分,结帖人jinxingfeng_cn]
http://bbs.csdn.net/topics/390612263?page=1#post-395768948
- 一个net程序猿必备工具
自古以来,人类的进步都是依赖于工具的进步,从刀耕火种,到使用青铜器,再到现在的科技,每一次都使我们的工作效率提高了无数倍,所以一个好的工具能使我们提高无数倍的工作效率,下面,我就根据自己简单的总结一下 ...
- 新建一个DataTable(只针对一列)
/// <summary> /// 新建一个DataTable(只针对一列) /// </summary> /// <param name="dataStr&q ...
- 关于只针对ie7浏览器的css问题
如代码: .centerDiv .search_k2{ margin-left: 18px; *margin-left: 9px; margin-top: 10px; height: 40px;} 中 ...
- WaitForSingleObject与WaitForMultipleObjects用法详解(好用,而且进入一个非常高效沉睡状态,只占用极少的CPU时间片)
在多线程下面,有时候会希望等待某一线程完成了再继续做其他事情,要实现这个目的,可以使用Windows API函数WaitForSingleObject,或者WaitForMultipleObjects ...
- 面试王牌 JAVA 多态只针对方法 不针对属性
子类是永远继承父类的非私有化方法,当子类中重写父类方法时,调用的是子类的方法,没有重写时,调用的是父类中的方法 1 多态是只针对方法,而不是属性的,但是写法上,子类重写父类的属性,编译器是不会报错的 ...
- 想让一个Widget成为模态,我们只需要对其设置setAttribute(Qt::WA_ShowModal, true);
想让一个Widget成为模态,我们只需要对其设置: setAttribute(Qt::WA_ShowModal, true); 注意:这是QWidget的成员函数 ,也就是说,QWidget可以显示为 ...
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- 每一个程序猿必知之SEO
似乎由于受这篇文章的影响 http://katemats.com/what-every-programmer-should-know-about-seo/ 于是我也觉得我应该写一个每一个程序猿必知之S ...
随机推荐
- HTML之Data URL(转)
Data URL给了我们一种很巧妙的将图片“嵌入”到HTML中的方法.跟传统的用img标记将服务器上的图片引用到页面中的方式不一样,在Data URL协议中,图片被转换成base64编码的字符串形式, ...
- Activity之间的数据传递(Arraylist)
1.使用Serialiable方法 实现序列化 2.使用Parcelable方法(这是android自己封装的类) Parcel类是封装数据的容器,封装后的数据通过Intent和IPC传递 实 ...
- Set Linux starts in multi-user mode as default.
ref: How to start Linux in multiuser mode rather than boot directly into XWindows (X11) steps: Log i ...
- [转]Delphi 快捷键 让你更像高手!!
新一篇: IDFTP 控件使用 >>代码模板 : CTRL+J >>代码整块移动 : CTRL+SHIFT+I(右移) CTRL+SHIFT+U(左移)>>选中窗体 ...
- centos 6.X 安装输入法
1.打开终端 su 输入 密码 yum install "@Chinese Support" 2.接下来是启用中文输入法的操作 系统 ->首选项 ->输入法 3.在弹出 ...
- 利用后缀数组(suffix array)求最长公共子串(longest common substring)
摘要:本文讨论了最长公共子串的的相关算法的时间复杂度,然后在后缀数组的基础上提出了一个时间复杂度为o(n^2*logn),空间复杂度为o(n)的算法.该算法虽然不及动态规划和后缀树算法的复杂度低,但其 ...
- Linux Chaining Operators用法学习
Linux Chaining Operators顾名思义,就是连接命令的操作,有些时候,往往一些命令可以用一行命令代替,我们就不需要大动干戈再去写Shell Script了,掌握和学习这些Chaini ...
- 12_RHEL7.1普通用户添加sudo权限
1.关于sudo Sudo是linux系统中,非root权限的用户提升自己权限来执行某些特性命令的方式,它使普通用户在不知道超级用户的密码的情况下,也可以暂时的获得root权限. 一 ...
- Tomcat安装阿里云免费证书
安装证书 Tomcat支持JKS格式证书,从Tomcat7开始也支持PFX格式证书,两种证书格式任选其一.下载包中包含PFX格式证书和密码文件. 1.PFX证书安装 找到安装 Tomcat 目录下该文 ...
- js 实现 C# 的 format 方法
2014-11-08 12:18:51 更新,修复原形链方法被当作关键词的bug,其实之前是想用全局关键词的,不过还是算了,array里有太多单词了. ...