避免重复值
问题描述:
我有一个建立的范围,我想从该范围内选择一组随机数(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++;
// ..................
答
最简单的方法(虽然不是最有效的)将可能是填充列表的所有元素,使用Collections.shuffle()
,然后选择第一个10%的元素。
由于排列不会有两次相同的进入(假设您使用这种方式填充它),所以前10%的元素也将是唯一的,因此它很适合。
答
如果您只需要整数范围的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;
答
使用collection.shuffle(),并选择指定大小的子列表,或者把你的价值观在一个列表,并在指数
found.add (list.remove (random.nextInt (list.size()));
为X次删除元素。在每一步中,列表的大小都会减小,并且没有元素会出现两次。
但是,对于非常大的范围 - 可以说有效长期的范围,建立一个列表来洗牌或从中挑选值是不合适的。
因此,创建一个Set,并选择随机值,将它们添加到列表中,直到set.size()等于您需要的大小。
Runnable的例子:
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]");
}
}
使用HashSet的,如果该号码不在集合,使用它,否则再生? – DarthVader
一个不相关的技巧:你可以使用ArrayList而不是你现在正在用int数组做什么。 –
AHungerArtist
@DarthVader没有哈希集(与任何一般哈希相同)自动销毁重复出现? – 2012-05-12 21:45:24