生成 N , 3 位唯一的随机整数,其中所有数字都是唯一的

Log*_*aul -1 java java-8

以下是我迄今为止尝试过的代码,它有效:

  public static void main(String[] args) {
    Random random = new Random();
    Integer[] integers = random.ints(10, 100, 999).boxed().toArray(Integer[]::new);
    List<Integer> list = new ArrayList<>();

    for (int i = 0; i < integers.length; i++) {
      String[] split = integers[i].toString().split("");
      int a = 0, b = 0, c = 0;
      a = Integer.valueOf(split[0]);
      b = Integer.valueOf(split[1]);
      c = Integer.valueOf(split[2]);
      if ((a != b) && (a != c) && (b != c)) {
        list.add(Integer.valueOf(integers[i]));
      }
    }
    list.forEach(System.out::println);
  }
Run Code Online (Sandbox Code Playgroud)

输出是正确的。

如果ABC是整数,然后a !=ba ! cb !=c,使所有的数字是独一无二的。

我尝试在流中应用后面的部分,但没有得到预期的结果。有人可以指导我哪里出错了吗?

Java-8 版本:

public static void main(String[] args) {

    Random random = new Random();
    Integer[] integers = random.ints(10, 100, 999).boxed().toArray(Integer[]::new);
    String[] collect = Arrays.stream(integers).map(s -> {
      String[] split = s.toString().split("");
      return split;
    }).filter(
        k -> (Integer.valueOf(k[0]) != Integer.valueOf(k[1])) && (Integer.valueOf(k[0]) != Integer
            .valueOf(k[2])) && (Integer.valueOf(k[1]) != Integer.valueOf(k[2])))
        .toArray(String [] ::new);
    Arrays.stream(collect).forEach(System.out::println);



  }
Run Code Online (Sandbox Code Playgroud)

And*_*eas 5

将数字转换为字符串并调用将split("")是您能想到的最慢的解决方案。

如果您有一个 3 位数字,并且您想要 3 位数字,请使用除法和余数运算符:

int i = /*assign some non-negative number of at most 3 digits*/;
int d1 = i / 100;
int d2 = i / 10 % 10;
int d3 = i % 10;
Run Code Online (Sandbox Code Playgroud)

如果您需要N数字,则无法生成N数字然后丢弃其中的一些。这将使你N数。您必须丢弃坏数字进行计数。

static int[] generate(int n) {
    // Numbers 100 and 101 contain duplicates, so lower limit is 102.
    // Upper limit is 987 (inclusive), since 988, 989, and 99x all contain duplicates.
    return new Random().ints(102, 988)
            .filter(Test::isThreeUniqueDigits)
            .limit(n)
            .toArray();
}
private static boolean isThreeUniqueDigits(int i) {
    int d1 = i / 100;
    int d2 = i / 10 % 10;
    int d3 = i % 10;
    return (d1 != d2 && d1 != d3 && d2 != d3);
}
Run Code Online (Sandbox Code Playgroud)

或者使用 lambda 表达式而不是方法引用:

static int[] generate(int n) {
    return new Random().ints(102, 988).filter(i -> {
                int d1 = i / 100, d2 = i / 10 % 10, d3 = i % 10;
                return (d1 != d2 && d1 != d3 && d2 != d3);
            }).limit(n).toArray();
}
Run Code Online (Sandbox Code Playgroud)

示例结果

int i = /*assign some non-negative number of at most 3 digits*/;
int d1 = i / 100;
int d2 = i / 10 % 10;
int d3 = i % 10;
Run Code Online (Sandbox Code Playgroud)

  • 经典答案!我还认为 `.split` 是最慢的。 (2认同)
  • 公平地说, .toString().split("")` 最昂贵的方面之一是转换为十进制表示形式,并除以 10 并取模(这是一个昂贵的经常被忽视的过程),而创建新字符串和数组(昂贵且经常被高估)并没有那么可怕,因为它们都很小。因此,这种方法保留了昂贵的数字提取和测试失败时重复生成随机数的过程。您可以仅使用乘法和加法[首先生成有效数字](/sf/answers/4185088421/)。 (2认同)