[英]How can I generate 4 random numbers with unrepeated digits
我想生成4 个随机数,它们不能有重复的数字。
例如4567
,(它没有像4557
这样的重复值)。
我希望它们是随机的。
有没有办法实现这一目标?
这将生成没有重复数字的 4 位随机数。
它的工作原理是生成 4 个唯一的数字,就像在电脑游戏中洗一副纸牌一样。 然后它通过乘法和加法简单地建立四位数。
如果数字小于1000
,则表示使用了0
并且在开头。 所以只需选择另一个数字进行调整。
Random r = new Random();
for (int k = 0; k < 10; k++) {
int val = gen(r);
System.out.println(val);
}
static int[] base = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public static int gen(Random r) {
int val = 0;
int s=10;
for (int i = 0; i < 4; i++) {
int n = r.nextInt(s);
val = val * 10 + base[n];
int save = base[n];
base[n] = base[--s];
base[s] = save;
}
return val < 1000 ? val * 10 + base[r.nextInt(s)] : val;
}
这是一个更直接的方法。 哲学与上述相同。 由于所有数字的洗牌,它可能不像以前那样有效。
// generate four digit numbers that have distinct digits.
List<Integer> digits = Arrays.asList(0,1,2,3,4,5,6,7,8,9);
Collections.shuffle(digits);
// now just use the first four of the shuffled list
if (digits.get(0) == 0) {
// for a 4 digit number, first digit can't be zero
// so choose another.
digits.set(0, digits.get(4));
}
// now use simple arithmetic to create the four digit number.
int n = 0;
for (int d : digits.subList(0,4)) {
n = n * 10 + d;
}
System.out.println(n);
我现在沉迷于流。 但是流很慢。 为了显示我写了以下主要方法的缓慢。 “generateWithLoop”方法涵盖了@WJS 的答案。
public static void main(String[] args) {
long nanoStart = System.nanoTime();
generateWithStreams();
long nanoEnd = System.nanoTime();
System.out.println("Elapsed time with Streams : " + (nanoEnd - nanoStart) + " nano seconds");
nanoStart = System.nanoTime();
generateWithLoop();
nanoEnd = System.nanoTime();
System.out.println("Elapsed time with Loop : " + (nanoEnd - nanoStart) + " nano seconds");
}
控制台输出:
Streams 已用时间:81367089 纳秒
循环运行时间:75093 纳秒
随着流:
public static void generateWithStreams() {
List<Integer> orderedList = getOrderedList();
for (int i = 0; i < 4; i++) {
List<Integer> shuffledList = getShuffledList(orderedList);
System.out.println(get4DigitNumber(shuffledList));
}
}
public static List<Integer> getOrderedList() {
return IntStream.range(0, 10).boxed().collect(Collectors.toList());
}
public static List<Integer> getShuffledList(List<Integer> list) {
return list.stream().sorted((o1, o2) -> ThreadLocalRandom.current().nextInt(-1, 2)).collect(Collectors.toList());
}
public static Integer get4DigitNumber(List<Integer> shuffledList) {
final Integer LIMIT = shuffledList.get(0).equals(0) ? 5 : 4;
return shuffledList.stream().limit(LIMIT).reduce(0, (sum, current) -> sum * 10 + current);
}
带循环:
public static void generateWithLoop() {
Random r = new Random();
for (int k = 0; k < 4; k++) {
int val = gen(r);
System.out.println(val);
}
}
static int[] base = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
public static int gen(Random r) {
int val = 0;
int s = 10;
for (int i = 0; i < 4; i++) {
int n = r.nextInt(s);
val = val * 10 + base[n];
int save = base[n];
base[n] = base[--s];
base[s] = save;
}
return val < 1000 ? val * 10 + base[r.nextInt(s)] : val;
}
public static void main(String[] args) {
List<Integer> list= new ArrayList<>();
for(int j = 0; j < 10; j++){
list.add(j);
}
Collections.shuffle(list);
String randomDigit= "";
for(int j = 0; j < 4; j++){
randomDigit+= list.get(j).toString();
}
System.out.println(randomDigit);
}
这是将字符串转换为 int。 但这会起作用,您可以使用它。
脚步:
List
,将保存生成的 4 位数字的每个单独的数字最终列表的大小现在是 4; 将这 4 个个体组合成一个String
,并转换为Integer
。
List<Integer> myNumber = new ArrayList<Integer>();
Random r = new Random();
// Generate a random number between 1 and 9 for units place
myNumber.add(r.nextInt(9) + 1);// adding 1 to avoid 0 in the units place
// Generate a random number between 0 and 9 for 10's and upcoming places
do {
Integer num = r.nextInt(10);
// Check the list doesn't contain that number
if (!myNumber.contains(num)) {
myNumber.add(num);
}
}while (myNumber.size() < 4);
StringBuilder numStr = new StringBuilder();
for (int i = 0; i < myNumber.size(); i++)
numStr.append(myNumber.get(i));
System.out.println(Integer.parseInt(numStr.toString()));
从Java-8开始使用stream
和Lambda 的解决方案:
public static void main(String[] args) {
Map<String, String> collect = IntStream.rangeClosed(1, 9).boxed()
.flatMap(x -> IntStream.rangeClosed(0, 9).boxed()
.flatMap(y -> IntStream.rangeClosed(0, 9).boxed()
.flatMap(z -> IntStream.rangeClosed(0, 9).boxed()
.flatMap(w -> IntStream.rangeClosed(1, 9).boxed().map(s -> s.toString()).filter(e -> noneRepete(x, y, z, w))
.map(k -> x.toString() + y.toString() + z.toString() + w.toString())))))
.collect(Collectors.toMap(Function.identity(), s -> s, (a, b) -> a));
collect.keySet().forEach(System.out::println);
}
public static boolean noneRepete(Integer a, Integer b, Integer c, Integer d) {
if (! a.equals(b) && ! a.equals(c) && ! a.equals(d) && a !=0) {
if (! b.equals(c) && ! b.equals(d)) {
return ! c.equals(d);
}
}
return false;
}
解释:
在这里,我们将整数流从 1 展平到 9(第一个数字不能为 0)。 同时,我们进一步将整数流从 0 展平到 9。上述过程又进行了 2 次,从而使其成为四位数字,我们有一个自定义过滤器,可确保所有四位数字都是唯一的。
最后,我们将它们收集为键和值,以确保数字是唯一的,并且映射中的键本身也是唯一的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.