如何生成具有特定范围的唯一随机数
how to generate unique random numbers with a specific range
我想生成 255 个在此范围 (0-255) 内的唯一随机数。这样数组就不会包含重复的记录
short [] array =new short[255];
Random rand = new Random();
boolean flag=false;
for (int i=0;i<array.length;i++){
int random_integer = rand.nextInt(255-0) + 0;
for (int j=0;j<i;j++){
if ((short)random_integer==array[j]){
flag=true;
}
}
if (flag==false){
array[i]=(short)random_integer;
}
}
for (int i=0;i<array.length;i++){
System.out.println(array[i]);
}
但我只得到前 20 0r 30 个有值的项目,其余数组项目为零。
如果没有适当的缩进,代码将很难阅读。
无论如何 - 如果 flag == true
,你什么都不做。所以很明显你没有填充数组中的很多地方。
你检查随机数是否存在,但你没有在你的循环中将标志重置为假,所以一旦第一个重复的数字出现,就不再发生任何事情,因为标志始终为真。
您还应该构建如下内容:
if ((short)random_integer==array[j]){
flag=true;
i--;
}
确保在跳过重复数字后重新访问数组的索引。
您需要在每次迭代中重置 flag
值或更改您的逻辑:
for (int j=0;j<i;j++){
flag=false;//<--
if ((short)random_integer==array[j]){
flag=true;
}
}
解决方案一:
我阅读了 Jon Skeet 的评论,当然,这是最简单的解决方案:
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 255; i++) {
list.add(i);
}
//and here is the point. Java already have this implemented for you
Collections.shuffle(list);
或者在Java8声明式中:
List<Integer> list= IntStream.range(0, 255)
.boxed()
.collect(Collectors.toList());
Collections.shuffle(list);
或
List<Integer> list = new ArrayList<>();
IntStream.range(0, 255).forEach(list::add);
Collections.shuffle(list);
解决方案 2(采用您的解决方案):
您需要为每个单元格生成编号,并检查该编号是否已存在:
short [] array =new short[255];
Random rand = new Random();
for (int i=0; i<array.length; i++) {
int random_integer = -1;
//generate integer while it exists in the array
while(exists(random_integer, array)) {
random_integer = rand.nextInt(255);
}
array[i] = random_integer;
}
现在,让我们检查它是否存在:
public boolean exists(int number, int[] array) {
if (number == -1)
return true;
for (int i=0; i<array.length; i++) {
if (number == array[i])
return true;
}
return false;
}
当然,你可以使用hashmap来加速exists()
方法,即将复杂度从O(n)降低到O(1);
您是否考虑过创建一个 HashSet 并将您使用过的值放入其中?
那么您的代码应该如下所示:
HashSet hs = new HashSet();
short [] array =new short[255];
Random rand = new Random();
for (int i=0;i<array.length;i++){
int random_integer = rand.nextInt(255-0);
if (!hs.contains(random_integer ))
{
array[i]=(short)random_integer;
hs.put(random_integer);
}
else{ //generate new integer}
}
如果可以使用java 8:
List<Integer> randIntegers = new Random().ints(1, 256).distinct().limit(255).boxed().collect(Collectors.toList());
public static void main(String ar[]){
short [] array =new short[255];
Random rand = new Random();
int random_integer;
boolean flag=false;
for (int i=0;i<array.length;i++){
random_integer = rand.nextInt();
for (int j=0;j<i;j++){
if ((short)random_integer==array[j]){
flag=true;
i--;
}
}
if (flag==false)
array[i]=(short)random_integer;
}
for (int i=0;i<array.length;i++)
System.out.print(" "+array[i]);
System.out.println();
}
我想生成 255 个在此范围 (0-255) 内的唯一随机数。这样数组就不会包含重复的记录
short [] array =new short[255];
Random rand = new Random();
boolean flag=false;
for (int i=0;i<array.length;i++){
int random_integer = rand.nextInt(255-0) + 0;
for (int j=0;j<i;j++){
if ((short)random_integer==array[j]){
flag=true;
}
}
if (flag==false){
array[i]=(short)random_integer;
}
}
for (int i=0;i<array.length;i++){
System.out.println(array[i]);
}
但我只得到前 20 0r 30 个有值的项目,其余数组项目为零。
如果没有适当的缩进,代码将很难阅读。
无论如何 - 如果 flag == true
,你什么都不做。所以很明显你没有填充数组中的很多地方。
你检查随机数是否存在,但你没有在你的循环中将标志重置为假,所以一旦第一个重复的数字出现,就不再发生任何事情,因为标志始终为真。
您还应该构建如下内容:
if ((short)random_integer==array[j]){
flag=true;
i--;
}
确保在跳过重复数字后重新访问数组的索引。
您需要在每次迭代中重置 flag
值或更改您的逻辑:
for (int j=0;j<i;j++){
flag=false;//<--
if ((short)random_integer==array[j]){
flag=true;
}
}
解决方案一:
我阅读了 Jon Skeet 的评论,当然,这是最简单的解决方案:
List<Integer> list = new ArrayList<>();
for (int i = 0; i < 255; i++) {
list.add(i);
}
//and here is the point. Java already have this implemented for you
Collections.shuffle(list);
或者在Java8声明式中:
List<Integer> list= IntStream.range(0, 255)
.boxed()
.collect(Collectors.toList());
Collections.shuffle(list);
或
List<Integer> list = new ArrayList<>();
IntStream.range(0, 255).forEach(list::add);
Collections.shuffle(list);
解决方案 2(采用您的解决方案):
您需要为每个单元格生成编号,并检查该编号是否已存在:
short [] array =new short[255];
Random rand = new Random();
for (int i=0; i<array.length; i++) {
int random_integer = -1;
//generate integer while it exists in the array
while(exists(random_integer, array)) {
random_integer = rand.nextInt(255);
}
array[i] = random_integer;
}
现在,让我们检查它是否存在:
public boolean exists(int number, int[] array) {
if (number == -1)
return true;
for (int i=0; i<array.length; i++) {
if (number == array[i])
return true;
}
return false;
}
当然,你可以使用hashmap来加速exists()
方法,即将复杂度从O(n)降低到O(1);
您是否考虑过创建一个 HashSet 并将您使用过的值放入其中? 那么您的代码应该如下所示:
HashSet hs = new HashSet();
short [] array =new short[255];
Random rand = new Random();
for (int i=0;i<array.length;i++){
int random_integer = rand.nextInt(255-0);
if (!hs.contains(random_integer ))
{
array[i]=(short)random_integer;
hs.put(random_integer);
}
else{ //generate new integer}
}
如果可以使用java 8:
List<Integer> randIntegers = new Random().ints(1, 256).distinct().limit(255).boxed().collect(Collectors.toList());
public static void main(String ar[]){
short [] array =new short[255];
Random rand = new Random();
int random_integer;
boolean flag=false;
for (int i=0;i<array.length;i++){
random_integer = rand.nextInt();
for (int j=0;j<i;j++){
if ((short)random_integer==array[j]){
flag=true;
i--;
}
}
if (flag==false)
array[i]=(short)random_integer;
}
for (int i=0;i<array.length;i++)
System.out.print(" "+array[i]);
System.out.println();
}