1

我正在做一个程序,其中随机生成 1-5 的 3 个数字。我想要它,以便在生成一个数字时,它不能再次生成。

就像我不能得到 121,只有 134 这样的东西

4

5 回答 5

5

您可以将所有可能的数字放入一个集合中。然后你随机将它们一个接一个“弹出”出来。

这种方法类似于Knuth 的 shuffle,它比检查是否已生成数字的简单方法更有效,因为后者可能不会终止。

于 2013-05-12T19:21:27.803 回答
1

1.将 3 个数字转换为单个 3 位数字。

2.收集某个集合中所有创建的数字(设置应该没问题)

3.如果新号码已经在集合中 - 再次生成它,直到它是全新的

public static void main(String[] args) {
    final int digits = 5;
    final int toGenarate = 10;
    Set<Integer> used = new HashSet<Integer>();

    int generated = 0;
    while (generated < toGenarate) {
        int number = generate(digits);
        while (used.contains(number)) {
            number = generate(digits);
        }
        used.add(number);
        generated++;
        System.out.println(number);
    }

}

private static int generate(final int digits) {
    final Random r = new Random();
    return r.nextInt(digits) * 100 + r.nextInt(digits) * 10 + r.nextInt(digits);
}
于 2013-05-12T19:21:11.560 回答
1

由于可能的结果集是如此之小,因此将它们全部枚举出来,将它们放入一个数据结构中,然后随机选择并删除它们是完全合理的。枚举也相当简单:您正在查找可能值集的笛卡尔积,并且有许多众所周知的方法可以完成此操作,只需在搜索框中输入即可。

于 2013-05-12T19:38:02.560 回答
0

如果您只想要 3 个随机数,请使用伪代码:

  1. 声明 3 个变量 r1、r2 和 r3
  2. r1 = getRandom(1, 5)。getRandom 是一个获取参数 1 和 2 之间的随机数的函数
  3. r2 = getRandom(1, 5)
  4. 而 r2 = r1 转到步骤 3
  5. r3 = getRandom(1, 5)
  6. 当 r1 = r3 或 r2 = r3 转到步骤 5

如果您有 3 个以上的数字,则可以使用外循环和 Map

我看到它现在在java中

import  java.util.*;
public class RandomSet{

    public static void main(String[]a){


        java.util.Random rnd = new java.util.Random ();
        final int high = 5, low = 1, ll = low - 1;
        int r1 = ll,r2 = ll,r3 = ll;

        r1 = rnd.nextInt(high - 1) + low;
        while(r2 == (ll) || r2 == r1){
            r2 = rnd.nextInt(high - 1) + low;
        }
        while(r3 == (ll) || r3 == r1 || r2 == r3){
            r3 = rnd.nextInt(high - 1) + low;
        }
        System.out.println("r1 " + r1 + "; r2 " + r2 + "; r3 " + r3);
        RandomSet app = new RandomSet();
        Set t = app.randomSet(5, 1, 3);
        Iterator i = t.iterator();
        System.out.println(" randomSet ");
        while(i.hasNext()){
            System.out.println(" " + i.next());
        }
    }

    public Set<Integer> randomSet(final int high, final int low, final int number){
        if(number > (high - low)){
            throw new RuntimeException("bad high low for number");
        }
        Map<Integer,Integer> rnds = new HashMap<Integer,Integer>();
        java.util.Random rnd = new java.util.Random ();
        int r1 = 0;
        while(rnds.size() < number){
            r1 = rnd.nextInt(high - 1) + low;
            rnds.put(r1, r1);
        }
        return rnds.keySet();

    }

}
于 2013-05-12T19:25:07.980 回答
0

这似乎是一个学生问题,因此不会包含太多代码。

假设你有一副牌,你想给一个玩家发一手牌。你会怎么做?你会拿一副牌,洗牌,然后发五张牌。但是,您的问题中没有卡片,而是有一个数字列表:

  1. 创建一个List<Integer>.
  2. 通过将整数 1 到 5 添加到列表中来初始化它。
    • 将此参数化:编写一个将大小作为参数的方法。
  3. 随机播放列表。看看Collections班级。
  4. 从列表中取出 3 个整数并将它们添加到新列表中。看看List.remove(int)返回的是什么。
    • 再次,参数化方法。

另一种不涉及洗牌的方法是:

  1. 创建一个List<Integer>.
  2. 通过将整数 1 到 5 添加到列表中来初始化它。
  3. 看第一个元素。以 3/5 的概率使用它。
  4. 看下一个元素。有 2 个或 3 个空位,还有 4 个号码。以开放槽数除以剩余整数数的概率,接受这个元素。
  5. 对下一个元素重复;有 1、2 或 3 个空位,还剩 3 个号码。概率为 1/3。2/3 或 3/3 接受这个元素。

使用笔和纸验证是否以 3/5 的概率选择列表中的任何整数。

于 2013-05-12T19:26:39.503 回答