避免重复值

时间:2012-05-12 21:43:06

标签: java

我建立了一个范围,我想从该范围中选择一组随机数(10%),同时确保它没有重复值。

我在程序中如何以及在何处编写此代码?

以下是摘录。

// Number of Items      
int range = numberOfItems [itemNumber - 1];
// Determine 10 percent of the given range
int tenPercentOfRange = (int)(range * 0.1);
int number = 0;
int[] numbers = new int[tenPercentOfRange];

int index = 0;

for(;index < tenPercentOfRange;)
{
  // Randomly select 10% of the items for a given item.
  number = (int) (range * Math.random()) + 1;
  if(!Arrays.asList(numbers).contains(number))
  {
    numbers[index] = number;
    index++; 
    // ..................

3 个答案:

答案 0 :(得分:2)

最简单的方法(虽然不是最有效)可能是使用所有元素填充列表,使用Collections.shuffle(),然后选择前10%的元素。

由于排列没有两次相同的主菜(假设你用这种方式填充),前10%的元素也是唯一的,所以它适合。

答案 1 :(得分:2)

使用collection.shuffle(),选择指定大小的子列表,或将值放在List中,并删除索引处的元素

found.add (list.remove (random.nextInt (list.size ())); 

X次。在每个步骤中,列表的大小都会减小,并且不会出现两次元素。

然而,对于非常大的范围 - 让我们说有效长度的范围,构建一个列表来随机播放或从中挑选值是不合适的。

所以创建一个Set,然后选择随机值,将它们添加到列表中,直到set.size()等于你需要的大小。

可运行的示例:

import java.util.*;

public class Empty {

    static Random random = new Random ();

    public static void main (String args [])
    {
        show (pick (10, 100));
        show (securePick (10, 100000));
    }

    static public List <Integer> pick (int n, int max) {
        List <Integer> result = new ArrayList <Integer> ();
        List <Integer> range = new ArrayList <Integer> (max);
        for (int i= 0; i < max; ++i)
            range.add (i);
        for (int i= 0; i < n; ++i)
            result.add (range.remove (random.nextInt (range.size ()))); 
        return result;
    }

    static public Set <Integer> securePick (int n, int max) {
        Set <Integer> result = new HashSet <Integer> ();
        while (result.size () < n)
            result.add (random.nextInt (max)); 
        return result; // <Integer> 
    }

    public static void show (List <Integer> liste)
    {
        System.out.print ("[");
        for (int i : liste)
            System.out.print (i + ", ");
        System.out.println ("\b\b]");
    }

    public static void show (Set <Integer> liste)
    {
        System.out.print ("[");
        for (int i : liste)
            System.out.print (i + ", ");
        System.out.println ("\b\b]");
    }
}

答案 2 :(得分:0)

如果只需要10%的整数范围,那么重复直到获得不同数字的方法会更有效。这使用LinkedHashSet来有效地检查重复项。

final int range = 1000, sampleSize = range / 10;
final Set<Integer> rnds = new LinkedHashSet<Integer>();
final Random r = new Random();
for (int i = 0; i < sampleSize;) if (rnds.add(r.nextInt(range) + 1)) i++;
System.out.println(rnds);
final int[] result = new int[sampleSize];
int i = 0;
for (int nr : rnds) result[i++] = nr;