nの自然数が0から始まり、 b
0からnの間の数であるとすると、を除く数をランダムに選択したいと思いますb
。
nが5の場合、選択する番号は{0,1,2,3,4,5}
bが4の場合です。
それから私のランダムな選択はからです{0,1,2,3,5}
これを行う方法は、random.nextInteger()が4を検出しなくなるまで、whileループを実行することです。
whileループを使用する以外に、これを行うのは簡単ですか?
私は簡単な拡張機能を書きます:
// N.B. : min is inclusive, max is exclusive; so range is: [min,max) - {toExclude}
public static int Next(this Random rand, int min, int max, int toExclude)
{
int v = rand.Next(min, max - 1);
if (v < toExclude)
return v;
return v + 1;
}
使用法:
var random = new Random();
var val = random.Next(0,6,4); // 6 because max is exclusive in C# random.Next()
必要に応じて、別のアプローチを次に示します。
import random
def random_unifrom(n,b):
assert b < n and n > 0 and b > 0
nMinusOneList = [i for i in range(n) if i != b]
lSize = len(nMinusOneList)
randIndex = random.randint(0, lSize-1)
return nMinusOneList[randIndex]
簡単にするために、これをpythonで書きました。nMinusOneList の作成の複雑さは O(n) です。ランダム インデックスの複雑度を返す方法は、使用しているランダム関数によって異なります。
最後に、while ループの代わりにこの方法を使用すると何も失うことはありませんが、while ループの方法を使用しても、ランダム関数がランダム (!!) であれば問題はありません。ただし、上記の私のアプローチでは、最初から必要のない数を除外しています。
C# では、Python で使用する 1 行は、リストを作成する際に x (for ループ インデックス) が b と等しくないという条件で、0 から n の範囲の for ループで構成される 2 行である可能性があります。すると、b を除外したリストが得られます。