关于java学习总结练习

学完进阶的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;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值