【问题标题】:Generation of pair of random numbers in java without repetition of pair在java中生成一对随机数而不重复对
【发布时间】:2015-09-07 13:25:10
【问题描述】:

我想生成一对随机数而不重复这对。我如何在 java 中实现它?

【问题讨论】:

  • 你的意思是这2个随机数不应该相等吗?
  • 分享到目前为止你尝试过的任何东西。
  • 你想这样做多久?对重复也意味着排序?也请分享你的尝试

标签: java random


【解决方案1】:
Random r = new Random();
int x, y;

do {
    x = r.nextInt();
    y = r.nextInt();
} while (x == y);

【讨论】:

  • 这根本不会重用任何数字,因此除了不再产生相同的对之外,它不会产生任何包含已使用数字的对。虽然这个问题很模糊,但我想只有同一对不应该被创建两次!?
  • 我没有完全理解他在问什么,而且他似乎没有回应 cmets 所以我给了他我认为他想要的东西(一对不相等的数字)。跨度>
【解决方案2】:

我们需要跟踪已经生成的对。以下代码应该这样做:

Random random = new Random();
Map<Integer, Integer> generated = new HashMap<Integer, Integer>();
int x,y;
do{
    x = random.nextInt();
    y = random.nextInt();
    if(!generated.containsKey(x) || generated.get(x) != y){
        generated.put(x, y);
        break;
    }
}while(true);

【讨论】:

    【解决方案3】:

    如果你需要2个以上的数字,这种方法可能更有效:

    List<Integer> integers = IntStream.range(1, 10)
            .boxed()
            .collect(Collectors.toList());
    
    Collections.shuffle(integers);
    
    System.out.println(integers.get(0));
    System.out.println(integers.get(1));
    

    【讨论】:

      【解决方案4】:

      据我了解您的问题,您希望生成随机数字对而不重复它们。为此,我们首先需要一个保存值的类,因为它是一对数字,我称之为元组。

      public class Tuple {
          private Integer first;
          private Integer second;
      
          public Tuple(int first, int second) {
              this.first = first;
              this.second = second;
          }
      
          public int getFirst() {
              return first;
          }
      
          public int getSecond() {
              return second;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
      
              Tuple tuple = (Tuple) o;
              return first.equals(tuple.first) && second.equals(tuple.second);
          }
      
          @Override
          public int hashCode() {
              int result = first.hashCode();
              result = 31 * result + second.hashCode();
              return result;
          }
      }
      

      然后我们需要一个生成器类来保存可能出现在一对中的最高整数。请注意,此数字限制了可能的对数,因为您可以将包含 1...n 个数字的元组作为第一个数字,并且对于它们中的每一个,再将 1...n 个数字作为第二个,您最多可以返回 n*n 个元组!

      public class RandomTuples {
          private final int highestInt;
          private final Set<Tuple> usedTuples = new HashSet<>();
      
          public RandomTuples(int highestInt) {
              this.highestInt = highestInt;
          }
      
          public Tuple nextTuple() {
              if (usedTuples.size() >= highestInt*highestInt) {
                  throw new RuntimeException("All possible tuples were used. " +
                          "Use a higher param when instantiating RandomTuples for more!");
              }
      
              Random rnd = new Random();
      
              Tuple tuple = Stream
                      .generate(() -> new Tuple(rnd.nextInt(highestInt), rnd.nextInt(highestInt)))
                      .filter(filterTuple -> !usedTuples.contains(filterTuple))
                      .limit(1).findFirst().get();
              usedTuples.add(tuple);
              return tuple;
          }
      }
      

      这里的异常至关重要,否则流将陷入死锁。它将 generate 新元组尝试获取至少一个匹配条目 (limit(1)),而 filter 将删除此条目,从而创建一个无限循环...

      然后你必须实例化 RandomTouples 类并调用生成方法来获取一个新的元组。当使用大量数字时,这可能会以非常糟糕的性能运行,因为它必须尝试可能的组合,直到找到尚未使用的组合。

      public class RandomTuplesExample {
      
          public static void main(String[] args) {
      
              RandomTuples randomTuples = new RandomTuples(10);
              for (int i = 0; i < 100; i++) {
                  Tuple tuple = randomTuples.nextTuple();
                  System.out.println("(" + tuple.getFirst() + ", " + tuple.getSecond() + ")");
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-06-24
        • 2015-07-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-06
        相关资源
        最近更新 更多