欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

一个简单的随机分组问题

程序员文章站 2022-05-19 17:36:40
...

背景

之前有个位朋友给我了一看了一段代码,大致意思是给一个列表,里面元素是人,需要将一个列表的用户随机分成两拨人,关键词是“随机”

List<String> allPerson = new ArrayList<String>();
		allPerson.add("何XX");
		allPerson.add("李XX");
		allPerson.add("屈XX");
		allPerson.add("刘XX");
		allPerson.add("王XX");
		allPerson.add("涂XX");
		allPerson.add("张XX");
		allPerson.add("方XX");
		allPerson.add("何XX");
		allPerson.add("周XX");
		List<String> aGroup = new ArrayList<String>();
		List<String> bGroup = new ArrayList<String>();
		for(int i=0; i<10; i++){
			String seedPerson = allPerson.get(new Random().nextInt(allPerson.size()));
			if(i%2==0){
				bGroup.add(seedPerson);
			}else{
				aGroup.add(seedPerson);
			}
			allPerson.remove(seedPerson);
		}
		
		//A组名单
		System.out.println("A组名单");
		for(String aStr:aGroup){
			System.out.println(aStr);
		}
		//B组名单
		System.out.println("B组名单");
		for(String bStr:bGroup){
			System.out.println(bStr);
		}

 大致意思是在将allPerson中的元素,随机分到aGroup bGroup 两个列表中去。核心的意思是每次从剩下的allPerson列表中随机取出(String seedPerson = allPerson.get(new Random().nextInt(allPerson.size()));

)一个员工,然后按照对2取模之后放到它应该的队列中去。

优化

看了这段代码以我对代码的审美标准,完全没有美感。于是很快的写了一段我认为美的代码:

List<String> allPerson = new ArrayList<String>();
		allPerson.add("何XX");
		allPerson.add("李XX");
		allPerson.add("屈XX");
		allPerson.add("刘XX");
		allPerson.add("王XX");
		allPerson.add("涂XX");
		allPerson.add("张XX");
		allPerson.add("方XX");
		allPerson.add("何XX");
		allPerson.add("周XX");
		List<String> aGroup = new ArrayList<String>();
		List<String> bGroup = new ArrayList<String>();
		
p = [aGroup ,bGroup ];
for(int i=0;i<allPerson.size();i++){
p[(int)(Math.random()*2)].add(list.get(i));
}

 写完给我朋友看了一下,被他一语道破,最后得出的结果根本不符合他的需求,因为他要求的是两个列表结果集合是要相同的大小,我写的算法两个列表的大小是随机的,所以这个写法是错的。

 

   被他指出之后,我重新想了一下该怎么写。应该先将列表随机排序一下,像这样的算法像我这样的懒人怎么会去开发呢,当然要依赖jdk中已经有的sdk工具。于是写了下面这段代码:

public void test() {
        List<String> allPerson = new ArrayList<String>();
        allPerson.add("何XX");
        allPerson.add("李XX");
        allPerson.add("屈XX");
        allPerson.add("刘XX");
        allPerson.add("王XX");
        allPerson.add("涂XX");
        allPerson.add("张XX");
        allPerson.add("方XX");
        allPerson.add("何XX");
        allPerson.add("周XX");
        List<String> aGroup = new ArrayList<String>();
        List<String> bGroup = new ArrayList<String>();
        Collections.shuffle(allPerson);
        vist(allPerson.iterator(), aGroup, bGroup);

        System.out.println(aGroup);
        System.out.println(bGroup);

    }
    private void vist(Iterator<String> it, List<String> aGroup, List<String> bGroup) {
        if (!it.hasNext()) {
            return;
        }
        aGroup.add(it.next());
        vist(it, bGroup, aGroup);
    }

 这里利用了Collections.shuffle()这个函数先将allPerson 打散,然后用的迭代函数vist遍历allPerson,在每次迭代的时候将aGroupbGroup参数位置互换一下,就能起到均匀给两个子列表添加记录了。当然这个遍历可以使用for循环用一个迭代子i++,每次判断取模之后是否为0,向两个子group中均匀添加数据。这种迭代的用法属于函数式编程的一个例子,每次看到迭代的方式实现一个函数,总感觉透着一股泥土般的清香,不是吗?