算法比赛(顺序,二分,分块)java练习的一些问题

需求:

在这里插入图片描述

思路:

1.组委会作为一个类,提供随机生成的,元素不重复的list集合,再分派给三个选手类。
2.三个选手类的共性是查询算法,但各自的方法不同,所以应考虑用继承,各选手类继承自定义的Competitor类。
3.为公平竞赛,三个选手类拿到的list应完全一样,即组委会不能对list有任何别的操作(如排序)
4.选手不能主动获取组委会的list,要组委会去发给选手。
5.为了实现第3,4点,使用接口监听,Competitor类去监听组委会传来的list。

如何生成随机的,元素不重复的list集合?

 LogUtil.YXLog("请输入比赛所用的整形数组的长度(以100为整数倍):");
 Scanner sc = new Scanner(System.in);
        int len = sc.nextInt();
        for(int i = 0;i < len;i++){
            list1.add(i);
        }
        for(int i = 0;i < list1.size();i++){
            int val = (int)(Math.random() * list1.size());
            list1.remove(list1.get(val));
        }
         Collections.shuffle(list1);
         LogUtil.YXLog("随机生成的,元素不重复的list1:"+list1);

说明:先顺序生成len长度的list,再遍历list,移除随机生成的0~list1.size()的数。
注:随机生成val如果一样也可以,最后list根据元素的位置去remove。例如,进行两次list1.remove(list1.get(3)),移除的也是不同的元素。
for循环条件小于list1.size(),不可写为常数,因为在执行时list长度动态减少,若是常数,则最后list为空。

数组集合的互相转换

1 集合转数组:

在这里插入图片描述
例:把mlist集合转为Integer型的数组arr

 static List<Integer> mlist = new ArrayList<>();
 mlist.add(1);
 mlist.add(32);
 mlist.add(27);
 arr = (Integer[]) mlist.toArray(new Integer[mlist.size()]);

例:把list集合转为String型数组strArr

List<String> list = new ArrayList<String>();
    	list.add("刘雯");
    	list.add("杨紫");
    	list.add("胡歌");
    	String [] strArr =  list.toArray( new String[]{});
    	System.out.println(Arrays.toString(strArr));//[刘雯, 杨紫, 胡歌]

2 数组转集合:
在这里插入图片描述

java接口监听

1.原理:

当范围对象的状态发生变化的时候,服务器自动调用监听器对象中的方法。

例如:创建一个“人”类Class Person

人拥有吃的方法public void eat(){},我们的目的就是,在这个人吃之前要提醒他洗手,所以我们就要监听这个人,不管他在什么时候吃,我们都要能够监听到并且提醒他洗手,通俗点讲这个就是监听器的作用(在吃之前提醒他洗手)。

2.组成:

2.1Java的时间监听机制涉及到三个组件:事件源、事件监听器、事件对象

2.2当事件源上发生操作时,它会调用事件监听器的一个方法,并且调用这个方法时,会传递事件对象过来

2.3事件监听器是由开发人员编写,开发人员在事件监听器中,通过事件对象可以拿到事件源,从而对事件源上的操作进行处理

3.实现:

3.1创建一个人类,人具有跑、吃的方法  (创建一个事件源)

3.2创建一个接口用来监视人的跑、吃   (事件监听器)

3.3创建一个事件对象,里面用来封装人(Person)这个对象  (事件对象)

3.4创建一个测试类,用来测试Java监听机制

实现步骤:
1.创建事件监听器

public interface onListener{
        void OnListener(List m);
    }`

2 .定义空的监听器对象

 private onListener listener;

3.将传递进来的事件监听器给2中空的监听器对象

 public void registerListener(onListener listener){
        this.listener = listener;
    }

4.判断listener是否为null,如果不为空,则执行监听器中的方法

if(this.listener!=null){
       this.listener.OnListener(list1);
   }

在想要监听的代码段再去执行4中操作,(比方说在A类的m1方法里)这里是期望传入list1进去,至此接口监听的“被监听者” 完成,接下来就是谁去监听的问题了。
例如:由Competitor类去监听,在该类的构造器中,可以这么写:

public class Competitors {
    public Competitors(String name,ZuWeiHui m){
        m.registerListener(new ZuWeiHui.onListener() {
            @Override
            public void OnListener(List st) {
            }
        });
    }
}

由于 Competitors类是三个选手类的父类,因此当执行

毫秒级计时和纳秒级计时

 System.currentTimeMillis();  //毫秒级
 System.nanoTime();         //纳秒级

上面两个方法可以显示当前时间,如果要实现计时,可以定义两个long型的变量(int型长度不够用),再把两个long的值相减。
如:

 long start = System.nanoTime();
 //  执行耗时操作
 long end = System.nanoTime();
 long Time = (end - start) /1000;    //除以1000得毫秒级单位

分块查询算法

分块查找要求给定的数据是块内无序,分块有序的,每一块的最小的元素不能小于上一块中最大的元素。若分了n块,索引数组的长度就是n,索引数组的每个元素均是各分块的最大值。分块查找时,先确定元素在哪一个分块,确定后,在分块内部在顺序查找。

线程池

Executors工厂类,可用来产生线程池。其中静态工厂方法 new FixedThreadPool(int nThreads)可以创建可重用的,固定线程数的线程池。

public class A{
 public static void main(String[] args)  {
   ExecutorService pool = Executors.newFixedThreadPool(2);
        pool.submit(new Runnable() {
            @Override
            public void run() {
//               执行run里的逻辑
            }
        });
         pool.submit(new Runnable() {
            @Override
            public void run() {
//               执行第二个run里的逻辑
            }
        });
	}
}

上面的写法和以下写法效果相同,只是下面的包装了Thread的实现类:

public class A implements Runnable{
	 public static void main(String[] args)  {
	 	 ExecutorService pool = Executors.newFixedThreadPool(2);
	 	   pool.submit(new A() {
            @Override
            public void run() {
//               执行run里的逻辑
            }
        });
		  pool.submit(new A() {
            @Override
            public void run() {
//               执行第二个run里的逻辑
            }
        });
	 }
}

打印工具类

当一个demo需要打印输出较多的语句,又希望统一控制是否打印语句时,可以自建打印工具类。

public class LogUtil {
    private static boolean bool = true;
    public static void YXLog(String str){
//        bool = false;
        if(bool){
            System.out.println(str);
        }
    }
}

用布尔值去控制是否打印,为真时,调用LogUtil.YXLog可以打印,当不想打印时,只需把bool值改为false。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值