2017-04-23 118 views
1

我在0-20的范围内产生的非重复的随机数的数组作为是否可以改变随机数的范围?

int[] numbers = {6,14,11,18,13}; 

现在,我想这些数字在0-10的范围内转换和欲导致非重复如好。

可能吗?

任何类型的建议,将不胜感激。

+2

仅仅通过2 – Turing85

+0

鸿沟我想到过,但它给像10和11 –

+0

的数字相同的结果,无论是除以2,每个号码为@ Turing85建议,或直接删除所有号码大于10任方式应该工作。 –

回答

2

除以2他们是一个很好的解决方案,因为你必须输入的相同的尺寸和它保持均匀度:

对于每数每隔数x在[0; 10,它可以来自两种numers [0; 20 [:2 * x和2 * x + 1。

它会给你像10和11的数字相同的结果,但谁在乎?

+0

我需要数组中的非重复数字,这是原因 –

+0

然后所阐明的问题是缺少一些细节。如果你需要不重复的数字,那么你的输入必须有最多10个不同的值。如果你有更多你不能。 – ghilesZ

+0

数字0-9在结果中出现频率是10次的两倍。 – Henry

1

如果随机生成的数字大于10,那么可以减去10。我知道这不是一个合适的解决方案,但它肯定会为你工作。

+0

对于小于10的数字它不起作用 –

+0

小于10的数字已经在范围内0-10 –

2

这里是我想出了三种方法:

// divide by 2 
Arrays.stream(numbers).map(x -> x/2); 
// subtract 10 from everything that's > 10 
Arrays.stream(numbers).map(x -> x > 10 ? x - 10 : x); 
// remove every number that's > 10 
Arrays.stream(numbers).filter(x -> x < 10); 

现在,我知道你不想重复号码,你应该通过调用distinct删除所有的重复。

+0

Upvoted for the减10选项,这应该工作AFAIK。 –

1

如果使用Java8,则可以使用下面的代码来生成唯一的随机数:

int[] rand = new Random().ints(0, 11).distinct().limit(5).toArray(); 

此代码生成5支独特的随机数范围从0到10分

0

范围0- 20包含21个数字,0-10包含11个数字。所以导致统一分布数字的唯一解决方案是取原始集合中0-10范围内的数字,并在11-20范围内丢弃数字。

+0

不,我不同意。如果“0-10”被均匀分配,那么为什么“0-20”不会被均匀分配? –

+0

@TimBiegeleisen问题是,如果您尝试使用0-20中的所有数字映射到0-10时,11个结果中的其中一个将比其他结果少。 – Henry

+0

好的,你可能是对的。 OP应清楚地告诉我们范围以及每个端点是否打开或关闭。 –

0

您可以使用if条件在增强for循环中迭代数组。您可以使用arraylist或任何其他数据结构来存储小于10的随机数,因此您已经具有非重复值。

ArrayList<Integer> numberList = new ArrayList<>(); 
for(int number:numbers){ 
    if(number<10){ 
     numberList.add(number); 
    } 
} 
0

一个可能的解决方案是使用具有double值的帮助程序数组。

该算法是下一步。

  1. 创建具有从原点数组双值和值的数组是通过2.
  2. 划分找出新的双阵列中的最大值。
  3. 缩放新双数组中的所有值。这应该通过将所有值乘以一个系数来完成。系数是coefficient = 10/max
  4. 将新的double数组转换为整数值。可能的策略之一是将双重价值取整。

注意

  • 这可能是这个解决方案有一些“错误”,并不会为随机数的所有组合工作。在这种情况下,应该改进将double值转换为整数。
  • 如果原点数组包含10个以上的值,则无法将数组映射到新数组。

这就是它的代码。

public static void main(String[] args) { 
    int[] numbers = { 6, 14, 11, 18, 13 }; 

    // crate a new array with double values 
    double[] newNumbers = new double[numbers.length]; 
    for (int i = 0; i < numbers.length; i++) { 
     newNumbers[i] = (double) numbers[i]/2; 
    } 

    // get coefficient 
    double max = maxValue(newNumbers); 
    double coefficient = 10/max; 

    // scale numbers 
    for (int i = 0; i < newNumbers.length; i++) { 
     newNumbers[i] = newNumbers[i] * coefficient; 
    } 
    int[] newIntNumbers = new int[newNumbers.length]; 
    for (int i = 0; i < newNumbers.length; i++) { 
     newIntNumbers[i] = (int) Math.round(newNumbers[i]); 
    } 

    System.out.println(Arrays.toString(newNumbers)); 
    System.out.println(); 
    System.out.println(Arrays.toString(newIntNumbers)); 
} 

private static double maxValue(double[] array) { 
    double max = Double.MIN_VALUE; 
    for (double num : array) { 
     max = Math.max(max, num); 
    } 
    return max; 
} 
+0

适用于大多数情况,但有一些错误,如您所说 –

+0

我没有深入从双倍转换到整数。如果你想要,你可以尝试改进这行代码'newIntNumbers [i] =(int)Math.round(newNumbers [i]);'。这应该可以解决这些'错误'。 –

+0

是的,一些时间值重复了像10,11等关闭数字 –