刚刚来到北京入职新公司,之前打定主意在新公司之后养成写技术博客的好习惯.
入职这几天,架构还未到位,每天无事可做便想起做个练手小程序,看看自己的基础还记得多少.
废话不多说,先介绍这个花式杀人法的要求.
"大于1的任意人数围成一个圈,从任意一人数起(写程序的时候我用的是List集合于是便选择从第一个元素数起了),每数7个人就杀死第7个人,然后从死者下一个人开始数起,直到再数7个人,再杀掉第7个人"
很无趣的杀人游戏.
那么我的思路是,这个游戏存在三种情况:
1)人数大于或者等于7个人的时候:
这个方法很简单就是从第一个开始遍历list集合(程序里是arr),遍历到第7个元素就杀掉这个元素.然后用迭代把杀掉元素之后的元素赋予新的索引并放到一个新的集合(brr)里.
这时还有杀掉的元素前面的元素.我选择从零开始遍历旧集合并且add到新的集合里(brr);add的特点就是在原有元素的后面有序的添加,所以并不用担心原有的元素顺序会被打乱
2)人数小于7人并且大于1人的时候
这个我选择用"%"对拿到的arr进行运算."7%arr.size()"得到的就是数完arr的size之后不够7个数再度从头开始数数到第7个元素的索引,但是不是真正的索引,所以需要-1(真正的程序员哪怕我不说为什么也明白的).
这个时候已经拿到索引了,直接杀掉这个索引上的元素,然后同上,用迭代器拿到后面的元素,从头遍历拿到前面的元素,然后放到一个新的集合里(还是brr)
3)人数只有一个人
这个人是幸存者
之后,我会选择用递归的方式不断的杀人,直到还剩下一个幸存者为止.然后返回这个幸存者.
但是这里有个两个需要注意的地方:
1)返回值要返回arr里的,因为最后一次进递归并没有把arr集合里的元素放到brr里,所以返回brr的话会得到一个"[ ]"
2)递归返回值的话最好设定一个全局变量,不然的话,递归会把第一次递归的结果返回.至于为什么(自己去debug)
这个小Demo用到的知识点并不多,只有迭代器与递归.
这是代码:
package Demo01; import java.util.ArrayList; import java.util.ListIterator; import java.util.Scanner; /** * Created by administration on 2017/5/31. * 约梭芬杀人法 * 一共会有三种情况,当人数大于7时 把第七个元素杀掉 然后以第八个元素为第一个新建一个数组/集合 * 当人数小于7时 从第一个开始数 数完之后再从头数一直数到第7个时 杀掉这个元素 然后再把剩下的元素放到新的数组/集合中 */ public class Demo03 { public static ArrayListcrr = new ArrayList<>(); public static void main(String[] args) { ArrayList list = new ArrayList<>(); for (int i = 0; i < 15; i++) { list.add(i); } kill(list); System.out.println(crr.toString()); } public static void kill(ArrayList arr){ ArrayList brr = new ArrayList<>(); if(arr.size() >= 7){ arr.remove(6); ListIterator integerListIterator = arr.listIterator(6); while (integerListIterator.hasNext()){ brr.add(integerListIterator.next()); } for(int i=0; i<6 ; i++) { brr.add(arr.get(i)); } }else /** * 首先遍历次数要确定 用"%"求余数 以余数为索引 杀掉元素 */ if(arr.size() > 1){ int i1 = (7 % arr.size())-1; arr.remove(i1); ListIterator integerListIterator = arr.listIterator(i1); while (integerListIterator.hasNext()){ brr.add(integerListIterator.next()); } for(int i=0; i 1){ kill(brr); }else{ crr.add(arr.get(0)); } } }