将列表在 n 大小的容器内随机排列。

huangapple go评论74阅读模式
英文:

Shuffle list within n size of bins in list

问题

我有一个Java列表,示例:

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22]

我想要对它进行洗牌,但是要在n大小的桶内进行。所谓的桶,我是指我想要先洗牌前5个元素,然后是接下来的5个元素,依此类推...
因此,其中一种期望的结果将是:

sorted = [3,5,4,2,1, 8,9,7,10,6, 14,11,12,15,13, 19,20,17,18,16, 22,21]

如何高效地实现这个目标?

英文:

I have a java list, example:

a = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22]

I want to shuffle it but within n size bins within. From bin, I meant, I want to shuffle first 5 elements, then next 5 and so on..
So, one of the the expected result will be:

sorted = [3,5,4,2,1, 8,9,7,10,6, 14,11,12,15,13, 19,20,17,18,16, 22,21]

How can I do it efficiently

答案1

得分: 4

将数组放入列表中并对子列表进行洗牌:

Integer[] array = new Integer[] {
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
    11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
    21, 22
};
List<Integer> list = Arrays.asList(array);
int binSize = 5;

for (int i = 0, n = list.size(); i < n; i += binSize) {
    int j = Math.min(i + binSize, n);

    Collections.shuffle(list.subList(i, j));
}

array = list.toArray(new Integer[] {});

System.out.println(Arrays.toString(array));
[2, 1, 3, 4, 5, 6, 8, 10, 7, 9, 13, 11, 15, 14, 12, 19, 16, 17, 20, 18, 22, 21]
英文:

Put the array into a list and shuffle the sublists:

        Integer[] array = new Integer [] {                                                    
            1, 2, 3, 4, 5, 6, 7, 8, 9, 10,                                      
            11, 12, 13, 14, 15, 16, 17, 18, 19, 20,                             
            21, 22                                                              
        };                                                                      
        List&lt;Integer&gt; list = Arrays.asList(array);                              
        int binSize = 5;                                                        
                                                                                
        for (int i = 0, n = list.size(); i &lt; n; i += binSize) {                 
            int j = Math.min(i + binSize, n);                                   
                                                                                
            Collections.shuffle(list.subList(i, j));                            
        }                                                                       
                                                                                
        array = list.toArray(new Integer[] { });                                
                                                                                
        System.out.println(Arrays.toString(array));
[2, 1, 3, 4, 5, 6, 8, 10, 7, 9, 13, 11, 15, 14, 12, 19, 16, 17, 20, 18, 22, 21]

答案2

得分: 0

Just shuffle each subList defined by the start and end of the bins. Since the subList provides a view of the list, they are shuffled in place so there is no need to create a new collection.

List<Integer> vals = new ArrayList<>(
     List.of(1,2,3,4,5,10,20,30,40,50,100,200,300,400,500,1000,2000));

shuffleBins(vals);
System.out.println(vals);

Prints

[4, 5, 2, 3, 1, 10, 40, 20, 50, 30, 400, 200, 300, 100, 500, 2000, 1000]

The method

public static void shuffleBins(int binSize,
        List<Integer> items) {
    
    int start = 0;
    for (int i = 0; i < items.size()/5; i++) {
        Collections.shuffle(items.subList(start, start+binSize ));
        start += binSize;
    }
    // finish up when items.size() % binSize != 0
    Collections.shuffle(items.subList(start, items.size() ));
}

If you want to make it more versatile you can provide a set of indices indicating the bin starts.

public static void shuffleBins(List<Integer> binStarts,
        List<Integer> items) {
    int start = 0;
    for (int i = 0; i < binStarts.size(); i++) {
        Collections
                .shuffle(items.subList(start, binStarts.get(i)));
        start = binStarts.get(i) + 1;
    }
    Collections.shuffle(items.subList(start, items.size()));
}
英文:

Just shuffle each subList defined by the start and end of the bins. Since the subList provides a view of the list, they are shuffled in place so there is no need to create a new collection.

List&lt;Integer&gt; vals = new ArrayList&lt;&gt; 
     (List.of(1,2,3,4,5,10,20,30,40,50,100,200,300,400,500,1000,2000));

shuffleBins(vals);
System.out.println(vals);

Prints

[4, 5, 2, 3, 1, 10, 40, 20, 50, 30, 400, 200, 300, 100, 500, 2000, 1000]

The method

	public static void shuffleBins(int binSize,
	        List&lt;Integer&gt; items) {
	    
	    int start = 0;
	    for (int i = 0; i &lt; items.size()/5; i++) {
	        Collections.shuffle(items.subList(start, start+binSize ));
	        start += binSize;
	    }
        // finish up when items.size() % binSize != 0
	    Collections.shuffle(items.subList(start, items.size() ));
	}

If you want to make it more versatile you can provide a set of indices indicating the bin starts.

public static void shuffleBins(List&lt;Integer&gt; binStarts,
		List&lt;Integer&gt; items) {
	int start = 0;
	for (int i = 0; i &lt; binStarts.size(); i++) {
		Collections
				.shuffle(items.subList(start, binStarts.get(i)));
		start = binStarts.get(i) + 1;
	}
	Collections.shuffle(items.subList(start, items.size()));
}

</details>



huangapple
  • 本文由 发表于 2020年8月3日 23:09:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/63232029.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定