3

我确实有以下代码用于获取随机整数

for (int i=1;i<=5;i++) {
  int rand= new Random().nextInt(10);
  Log.d("Ramdom number", String.valueOf(rand));
}

问题是我不想重复随机数,这意味着当我运行这段代码时,它给了我 5 个数字,但其中两个至少重复。有什么建议吗?

4

8 回答 8

7

对于小范围的数字可供选择,这应该可以解决问题:

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());
}
于 2012-05-28T13:42:41.037 回答
1

问题是您正在循环中创建一个 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()]);
}
于 2012-05-28T13:34:54.727 回答
1
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 个非重复数字可能需要很长时间。maxvaluenumbers

另一个更具可扩展性的版本是有一个数字列表:

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);
于 2012-05-28T13:52:25.053 回答
0

因此,您要查找的不是随机数列表,而是随机排序的 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,我会开始担心。

于 2012-05-28T13:38:59.480 回答
0

我认为您需要一组随机数。这个提示应该足够了。

如果没有,请发表评论。

于 2012-05-28T13:46:13.163 回答
0

您可以维护一个生成数字的列表

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);

        }
}

您可以维护生成数字的向量并检查

该号码是否已经生成然后生成新号码

否则显示此号码

于 2012-05-28T13:46:23.317 回答
0

你想要的是随机组合,使用哈希表避免重复

从我的脑海中,代码应该是这样的:

    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);

如果重复,则仅覆盖该值,因此只有不同的绘制数字才会在哈希表中具有条目。

于 2012-05-28T13:55:03.837 回答
-1

您可以将生成的数字保存在集合中,并且仅当随机数不在集合中时才使用它

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);
      } 
    }  
于 2012-05-28T13:42:25.317 回答