我想随机数但上面的编码没有重复是正确的吗?
i would like to random number but no repetition im coding above is it correct?
我想做的是生成随机数但没有重复我在上面编码是否正确?
public static void main(String[] args) {
ArrayList<Integer> arrayLast = new ArrayList<Integer>();
for (int arrayitems : getArray(10, 100)) {
arrayLast.add(arrayitems);
}
}
public static ArrayList<Integer> getArray(int arraysize, int range){
ArrayList<Integer> array = new ArrayList<Integer>();
ArrayList<Integer> arraybase = new ArrayList<Integer>();
Random rnd = new Random();
for (int i = 1; i <= range; i++) {
arraybase.add(new Integer(i));
}
int k =0;
for (int j = 0; j < arraysize; j++) {
if(range>arraysize) {
int sayi = rnd.nextInt(range-arraysize);
array.add(arraybase.get(sayi));
arraybase.remove(sayi);
}
else {
int sayi = rnd.nextInt(arraysize-k);
array.add(arraybase.get(sayi));
arraybase.remove(sayi);
k++;
}
}
Collections.shuffle(array);
return array;
}
您的逻辑不必要地复杂。更简单的方法如下:
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> set = new HashSet<Integer>();
final int SIZE = 10;
final int RANGE = 100;
Random random = new Random();
while (set.size() != SIZE) {
set.add(random.nextInt(RANGE));
}
System.out.println(set);
}
}
样本运行:
[83, 67, 86, 39, 56, 26, 92, 60, 13, 94]
请注意,Set
仅保留唯一值。因此,添加到其中的任何重复随机数将被自动丢弃。
或者,
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
final int SIZE = 10;
final int RANGE = 100;
Random random = new Random();
List<Integer> list = IntStream.generate(() -> random.nextInt(RANGE)).distinct().limit(SIZE).boxed()
.collect(Collectors.toList());
System.out.println(list);
}
}
样本运行:
[54, 62, 14, 5, 30, 76, 7, 9, 63, 61]
使用 Java 8+ 中的 Stream API,您可以生成 n
个不同的整数,范围从 origin
(含)到 bound
(独家)通过使用此方法:
public static List<Integer> randomInts(int n, int origin, int bound) {
return ThreadLocalRandom.current().ints(origin, bound)
.distinct()
.limit(n)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}
示例:
// generate 15 distinct random numbers greater than or equal to 10 and less than 90
List<Integer> randoms = randomInts(15, 10, 90);
我推荐这样做。如果大小和范围明显不同,则可以使用 sets
或 streams
和 distinct
。但如果大小和范围接近,这些方法可能需要相对较长的时间才能完成。
这个算法的缺点是它首先初始化了一个内部数组。我发现这在大多数情况下是微不足道的,并且对于大小和范围都很大的值,速度的提高非常显着。
它的工作原理如下:
- 假设一个从
0
到 N
的整数数组。
- 在
0
和N
之间生成一个随机整数k
- 将该值分配给 return 数组。
- 用第 N 个值替换第 k 个值
- 然后将
N
减少 1
- 并重复直到
N == 0
由于 k
已从可用值列表中有效删除并替换为未分配的 Nth
值,因此永远不会再次选择该值。
public static int [] getRandom(int size, int range) {
Random r = new Random();
int[] ret = new int[size];
// initialize number pool
int[] nums = IntStream.range(0,range).toArray();
for (int i = 0; i < size; i++) {
int k = r.nextInt(range);
ret[i] = nums[k];
range--;
nums[k] = nums[range];
}
return ret;
}
为了对此进行测试,我推荐以下内容。该集合被填充只是为了表明没有重复项。具有讽刺意味的是,填充集合来证明一个点比实际生成值需要更多的时间。
int[] v = getRandom(10_000_000, 10_000_000);
System.out.println("Done! Filling set");
Set<Integer> set = Arrays.stream(v)
.boxed()
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.printf("%,d%n",set.size());
System.out.printf("%,d%n",v.length);
版画
Done! Filling set.
10,000,000
10,000,000
我想做的是生成随机数但没有重复我在上面编码是否正确?
public static void main(String[] args) {
ArrayList<Integer> arrayLast = new ArrayList<Integer>();
for (int arrayitems : getArray(10, 100)) {
arrayLast.add(arrayitems);
}
}
public static ArrayList<Integer> getArray(int arraysize, int range){
ArrayList<Integer> array = new ArrayList<Integer>();
ArrayList<Integer> arraybase = new ArrayList<Integer>();
Random rnd = new Random();
for (int i = 1; i <= range; i++) {
arraybase.add(new Integer(i));
}
int k =0;
for (int j = 0; j < arraysize; j++) {
if(range>arraysize) {
int sayi = rnd.nextInt(range-arraysize);
array.add(arraybase.get(sayi));
arraybase.remove(sayi);
}
else {
int sayi = rnd.nextInt(arraysize-k);
array.add(arraybase.get(sayi));
arraybase.remove(sayi);
k++;
}
}
Collections.shuffle(array);
return array;
}
您的逻辑不必要地复杂。更简单的方法如下:
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
public class Main {
public static void main(String[] args) {
Set<Integer> set = new HashSet<Integer>();
final int SIZE = 10;
final int RANGE = 100;
Random random = new Random();
while (set.size() != SIZE) {
set.add(random.nextInt(RANGE));
}
System.out.println(set);
}
}
样本运行:
[83, 67, 86, 39, 56, 26, 92, 60, 13, 94]
请注意,Set
仅保留唯一值。因此,添加到其中的任何重复随机数将被自动丢弃。
或者,
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
final int SIZE = 10;
final int RANGE = 100;
Random random = new Random();
List<Integer> list = IntStream.generate(() -> random.nextInt(RANGE)).distinct().limit(SIZE).boxed()
.collect(Collectors.toList());
System.out.println(list);
}
}
样本运行:
[54, 62, 14, 5, 30, 76, 7, 9, 63, 61]
使用 Java 8+ 中的 Stream API,您可以生成 n
个不同的整数,范围从 origin
(含)到 bound
(独家)通过使用此方法:
public static List<Integer> randomInts(int n, int origin, int bound) {
return ThreadLocalRandom.current().ints(origin, bound)
.distinct()
.limit(n)
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}
示例:
// generate 15 distinct random numbers greater than or equal to 10 and less than 90
List<Integer> randoms = randomInts(15, 10, 90);
我推荐这样做。如果大小和范围明显不同,则可以使用 sets
或 streams
和 distinct
。但如果大小和范围接近,这些方法可能需要相对较长的时间才能完成。
这个算法的缺点是它首先初始化了一个内部数组。我发现这在大多数情况下是微不足道的,并且对于大小和范围都很大的值,速度的提高非常显着。
它的工作原理如下:
- 假设一个从
0
到N
的整数数组。 - 在
0
和N
之间生成一个随机整数k
- 将该值分配给 return 数组。
- 用第 N 个值替换第 k 个值
- 然后将
N
减少1
- 并重复直到
N == 0
由于 k
已从可用值列表中有效删除并替换为未分配的 Nth
值,因此永远不会再次选择该值。
public static int [] getRandom(int size, int range) {
Random r = new Random();
int[] ret = new int[size];
// initialize number pool
int[] nums = IntStream.range(0,range).toArray();
for (int i = 0; i < size; i++) {
int k = r.nextInt(range);
ret[i] = nums[k];
range--;
nums[k] = nums[range];
}
return ret;
}
为了对此进行测试,我推荐以下内容。该集合被填充只是为了表明没有重复项。具有讽刺意味的是,填充集合来证明一个点比实际生成值需要更多的时间。
int[] v = getRandom(10_000_000, 10_000_000);
System.out.println("Done! Filling set");
Set<Integer> set = Arrays.stream(v)
.boxed()
.collect(Collectors.toCollection(LinkedHashSet::new));
System.out.printf("%,d%n",set.size());
System.out.printf("%,d%n",v.length);
版画
Done! Filling set.
10,000,000
10,000,000