pbadcefp 的答案可能是最简单的。由于您在 cmets 中声明您需要它是“动态的”,因此这是另一种方法。请注意,权重基本上指定了要从中选择的数字在数组中出现的频率
public int weightedRandom( Random random, int max, Map<Integer, Integer> weights ) {
int totalWeight = max;
for( int weight : weights.values() ) {
totalWeight += weight - 1;
}
int choice = random.nextInt( totalWeight );
int current = 0;
for( int i = 0; i < max; i++ ) {
current += weights.containsKey( i ) ? weights.get( i ) : 1;
if( choice < current ) {
return i;
}
}
throw new IllegalStateException();
}
示例用法:
Map<Integer, Integer> weights = new HashMap<>();
weights.put( 1, 0 ); // make choosing '1' impossible
weights.put( 4, 3 ); // '4' appears 3 times rather than once
int result = weightedRandom( new Random(), 5, weights );
基本上,这相当于pbadcefp的解决方案应用于数组{ 0, 2, 3, 4, 4, 4 }
如果你想使用百分比,你必须适应这个。只需相应地计算权重。另外,我没有对此进行测试,因此您可能需要更广泛地对其进行测试。
这绝不是一个完整的解决方案,但比起完整的解决方案,我更喜欢提供一些东西来解决,因为你应该自己做一些工作。
我也将继续记录并说恕我直言,这是过度设计的;但你想要这样的东西。