我确实有以下代码用于获取随机整数
for (int i=1;i<=5;i++) {
int rand= new Random().nextInt(10);
Log.d("Ramdom number", String.valueOf(rand));
}
问题是我不想重复随机数,这意味着当我运行这段代码时,它给了我 5 个数字,但其中两个至少重复。有什么建议吗?
对于小范围的数字可供选择,这应该可以解决问题:
ArrayList<Integer> numbers = new ArrayList<Integer>();
for (int i = 0; i < 20; ++i) {
numbers.add(i);
}
Collections.shuffle(numbers);
for (int i = 0; i < 5; ++i) {
Log.d("Random number", numbers.get(i).toString());
}
问题是您正在循环中创建一个 Random 对象。如果循环是“紧”的,就像在这种情况下,随机对象将使用相同的值播种。将 Random 对象初始化移到循环之外应该可以解决问题。
Random r = new Random();
for (int i=1;i<=5;i++) {
int rand= r.nextInt(10)
Log.d("Ramdom number", String.valueOf(rand));
}
编辑:
这应该有效(至少它对我有用)
public static Integer[] getRangedInt(int maxRange, int numCount)
{
if (maxRange < numCount)
{
throw new Exception("maxRange cannot be smaller than numCount");
}
Set<Integer set = new HashSet<Integer>();
Random r = new Random();
while (Set.size() < numCount)
{
int random = r.nextInt(maxRange);
while (!set.add(random))
{
random = r.nextInt(maxRange);
}
}
return set.toArray(new Integer[set.size()]);
}
final int maxnumbers = 5;
final int maxvalue = 10;
final Random generator = new Random();
Set<Integer> numbers = new HashSet<Integer>();
while(numbers.size() < maxnumbers){
numbers.add(random.nextInt(maxvalue));
}
在此循环之后,您应该在 0 和setmaxnumber
之间有不重复的随机数。您必须小心,以免在使用此方法时迭代次数过多,即从 10000 个中生成 9999 个非重复数字可能需要很长时间。maxvalue
numbers
另一个更具可扩展性的版本是有一个数字列表:
List<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i<maxvalue; i++){ numbers.add(i); }
Collections.shuffle(numbers);
List<Integer> randomnums = numbers.subList(0, maxnumbers);
因此,您要查找的不是随机数列表,而是随机排序的 30 个数字的列表。
一种方法是生成所有可能值的列表,然后将它们随机排序,然后根据需要将它们从列表的前面剥离。这是一些伪代码:
for(int i=1; i<=30; i++) {
double r = rand();
while (null != aTreeSet.get(r)) r = rand();
aTreeSet.put(r, i);
}
whererand()
返回一些随机值(不是您寻求的 1-30,即i
),可能介于 0 和 1 之间,aTreeSet
这就是您的想法。
循环防止在 dup 返回的不太可能的情况下感到悲伤rand()
。
aTreeSet
要使用它,请按排序顺序从中提取值。
编辑 -总解决方案
另一种方法是生成 1-30 值,如果它还没有在“我已经看到这个”集合中,则添加它并返回该值。如果存在,则生成一个新的随机数。重复直到发现未使用的号码。对于最后几个值,相对而言,这表现不佳。对于现代处理器上的 30 个值,它当然会在几毫秒内完成。如果您的最大值是 1,000 而不是 30,我会开始担心。
我认为您需要一组随机数。这个提示应该足够了。
如果没有,请发表评论。
您可以维护一个生成数字的列表
boolean flag=false;
Vector<int> vec = new Vector<int>();
for (int i=1;i<=5;i++) {
flag=false;
int rand= r.nextInt(10);
for(int j=0;j<vec.size();j++)
{
if(vec.get(j)==rand)
{
flag=true;
break;
}
}
if(flag)
{
continue;
}
else
{
Log.d("Ramdom number", String.valueOf(rand));
vec.add(rand);
}
}
您可以维护生成数字的向量并检查
该号码是否已经生成然后生成新号码
否则显示此号码
你想要的是随机组合,使用哈希表避免重复
从我的脑海中,代码应该是这样的:
Ramdom r = new Random();
Hashtable<Integer, Integer> h = new Hashtable<Integer, Integer>();
while( h.keys().size() < 5 ) {
int i = r.nextInt(10);
h.put(i,i);
}
Integer[] k = (Integer[]) h.keySet().toArray();
线
h.put(i,i);
如果重复,则仅覆盖该值,因此只有不同的绘制数字才会在哈希表中具有条目。
您可以将生成的数字保存在集合中,并且仅当随机数不在集合中时才使用它
Random r = new Random();
Set<Integer> generatedNumbers = new HashSet<Integer>();
for(int i = 1;i<=5;i++) {
int rand = r.nextInt(10)
if (!generatedNumbers.contains(rand)) {
Log.d("Ramdom number", String.valueOf(rand));
generatedNumbers.add(rand);
}
}