约瑟夫环的问题内容是:
古代某位法官要判决n个犯人死刑,他有一条荒唐的法律:让n个犯人站成一个圆圈,从第s个人开始数起,每数到第d个犯人时就将其拉出来处决;然后再数d个,数到的人再被处决......直到剩下最后一个可以被赦免。
解析:
(1)由于无法预知犯人个数,并需对其进行操作,可以考虑使用向量类。
(2)初始化。创建一个vector类的向量对象v,使用泛型。执行方法v.add(),将犯人的序号打包成Integer对象,添加到向量v中。
(3)设置current为当前欲删除的元素的下标。如果从第1个人开始数起,则current的初值应设置为第一个人的前一位,即current=s-1。
(4)循环。当v中元素多于1个时(v.size()>0),调用v.remove()方法删除下标为current的元素。current的值一直在增加,但既不能超过数组下标范围,又要实现环形结构。所以current的变化规律是current=(current+1)%v.size(),其中v.size()是v的实际元素个数,每删除一个元素,v.size()的值少1。
(5)为了更好的了解向量中的元素情况,每次循环都输出向量中的全部元素值,调用(Integer)v.get(i)方法将获得的下标为i的Object类元素转化为Integer对象,再调用Integer类的intValue()方法输出相应的int值。
(6)当循环停止,向量v中只剩下一个元素,这就是要找的人。
import java.util.Vector;
public class JosePhus {
public static void main(String args[]){
int n=7,s=2,d=4;
Vector<Integer>v=new Vector<Integer>(n);
for(int i=0;i<n;i++){
v.add(i);
}
int current=s-1;
while(v.size()>1){
System.out.println("Vector: ");
for(int i=0;i<v.size();i++){
System.out.println((v.get(i)).intValue()+" ");
}
int j=0;
while(j<d){
current=(current+1)%v.size();
j++;
}
System.out.println("\tcurrent="+current+" ");
v.remove(current);
}
System.out.println("被赦免者是:"+(v.get(0)).intValue());
}
}