序
学完进阶的api后,对面对对象,多态,接口,集合有了一定的了解,但还不太熟练,于是找来黑马的题来练习一下,主要是对之前学过的知识复习一下,并且锻炼一下编程思维,之后也会多发布一些有意思的算法题。
题目
题目意思很简单,但是实现需求可能有一点点复杂,大概意思是,我有100个人,现在要从1-200的随机数(不重复)的编号分给他们,将100个人列队排好,每次去掉奇数位置的人,最后剩下的那个人就是幸存者,我们要找到他的编号和位置是多少(听起来有些残忍)
分析思路
首先100个人我们可以设立对象去操作,里面封装一些我们需要用到的数,比如位置信息,编号等,然后可以用集合去包装这些对象,方便我们做之后的处理,然后设立随机值,可以用random去解决,但是这里需要注意不能重复,所以我们还需要进行一个重复的判定。分完编号后我们开始去除奇数位置的人,这里是一个重点,假如我们从一开始正着去除,每次去掉第一个人后,位置都会发生改变,很是麻烦,因为我们没办法一次性去掉奇数位的人,只能一个一个循环去除,所以我们只好换一个思维。还有一个办法,就是从后往前倒着去除,这样的好处是,后面去除的,前面位置不会发生影响,方便我们循环。但是有一个问题是,倒着去除要考虑这个集合是偶数还是奇数,这影响我们去除的顺序,是从最后一个开始去除还是从倒数第二个去除。这里还有一个更好的办法:我们设立一个备份集合,去掉奇数位置的人相当于保留偶数位的人,我们从原来集合偶数位人保留到新集合里来,这样去遍历是不是相对好操作一些?从集合中取出元素这个我们再熟悉不过了,通过一个循环就可以搞定。
代码实现
首先是再熟悉不过的people对象搞起来
public class People {
private int code;//编号
private int location;//位置
public int getCode() {
return code;
}
public int getLocation() {
return location;
}
public void setCode(int code) {
this.code = code;
}
public void setLocation(int location) {
this.location = location;
}
public People(int code, int location) {
this.code = code;
this.location = location;
}
public People() {
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Test1 {
public static List<People>peoplelist = new ArrayList<>();
public static void main(String[] args){
//创建100个囚犯,依次占位,并为赋值编号,不能重复
Random r = new Random();
for(int i =1;i<=100;i++){
while(true){//由于需要判断是否重复,需要加入死循环,如果重复就继续生成随机数,不重复就跳出循环,生成下一个随机数
int code = r.nextInt(200) + 1;//1到200的随机数
//检查是否唯一
if (!isRepeat(code)) {
People p = new People(code, i);
peoplelist.add(p);//添加到集合里
break;
}
}
}
System.out.println("囚犯占位:"+peoplelist);
//删除奇数位的人相当于留下偶数位置的人
while (peoplelist.size()>1){
List<People> tempeoplelist = new ArrayList<People>();//多态的写法
for(int i =1;i<peoplelist.size();i+=2){
//[0,1,2,3,4,5,6]
// 1 2 3 4 5 6 7
// peoplelist.get(i);
tempeoplelist.add(peoplelist.get(i));
}
peoplelist=tempeoplelist;
}
//最后输出剩下一个人的编号和位置
People luckPeople = peoplelist.get(0);
System.out.println(luckPeople);
}
//定义一个判定编号是否重复的方法
//这里有一个细节,如果我们直接将集合放进去,一个一个对照会对内存造成不小的负担,所以我们将集合设立为static静态,相当于常量
public static boolean isRepeat(int code){
for(People people:peoplelist){
if(people.getCode()==code)
{
return true;
}
}
return false;
}
}