[英]Avoid repeating values
I have a range established and I want to select a set of random numbers from that range (10%) while making sure it does not have repeating values. 我建立了一个范围,我想从该范围中选择一组随机数(10%),同时确保它没有重复值。
How and where do I code this within my program? 我在程序中如何以及在何处编写此代码?
Below is an extract. 以下是摘录。
// 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++;
// ..................
The easiest way (though not most efficient) will probably be to populate a list with all elements, use Collections.shuffle()
, and select the first 10% elements. 最简单的方法(虽然不是最有效)可能是用所有元素填充列表,使用Collections.shuffle()
,并选择前10%的元素。
Since the permutation does not have the same entree twice (assuming you populated it this way), the first 10% elements will also be unique, so it fits. 由于排列没有两次相同的主菜(假设你用这种方式填充),前10%的元素也将是唯一的,所以它适合。
Use collection.shuffle (), and pick a sublist of specified size, or put your values in a List, and remove element at index 使用collection.shuffle(),并选择指定大小的子列表,或将您的值放在List中,并在索引处删除元素
found.add (list.remove (random.nextInt (list.size ()));
for X times. 为X次。 In each step the list is reduced in size, and no element will appear twice. 在每个步骤中,列表的大小都会减小,并且不会出现两次元素。
However, for very big ranges - lets say the range of valid longs, building a list to shuffle or to pick values from isn't appropriate. 但是,对于非常大的范围 - 假设有效长度的范围,构建列表以随机播放或从中挑选值是不合适的。
So create a Set, and pick random Values, add them to the list until the set.size () is equals the size you need. 因此,创建一个Set,并选择随机值,将它们添加到列表中,直到set.size()等于您需要的大小。
Runnable examples: 可运行的例子:
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]");
}
}
Your approach with repeating until you get a distinct number is more efficient if you need only 10% of the integer range. 如果只需要10%的整数范围,那么重复直到获得不同数字的方法会更有效。 This uses LinkedHashSet
for efficient check for duplicates. 这使用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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.