创建具有特定要求的随机数字字符串

时间:2016-01-08 02:30:16

标签: java

我想创建一个随机的数字字符串。

  • 从0-9。
  • 10位数。
  • 第一个数字不能为0。
  • 其中一个数字必须在字符串中2次,其中一个必须不在那里。
  • 或者一个数字必须在那里3次,其他2个数字根本不存在。

为了使这一点更清楚,这里有一些例子:

1223456789 - 10位数字,没有开始零,一位数字(2)有2次,一位数字(0)根本没有

1000345678 - 10位数,没有起始零,一位数(0)有3次,两位数(2,9)根本没有

使用startsWith方法很容易捕获起始零点,但是我还没有找到一种方法来检查其余的并且我不是特别擅长正则表达式,而我也不完全确定你甚至可以使用正则表达式来做到这一点。

为了生成随机字符串本身,我使用了Random类和RandomStringUtils,两者都没有创建数字的限制。

你们中有谁知道如何实现这个目标吗?

4 个答案:

答案 0 :(得分:1)

想象一下,你有10个麻袋,每个麻袋都有相应的数字,从0到9,如下:

   .---.._                  
  {------'; 
   }====={    
 .´       '.   
/    .´|    \       inside there are
|      |    |  <--- stones with '1' engraved
\:    _|_   /
  -__    =.´

你还有一枚硬币可以翻转你手上的头或尾。

       .------..-                  
     ´  . /___  `.`.
   ;   / /    ´}  ; ;     ______________________________ 
  :    "|'__'  //  : :   /                              |
  '    .|/__\. } \ ' '  /_    HEAD! You shall pick 3    |
  '     /"../      ' '    |  stones from the 1st sack!  |
   ;   /  \/  ͷ   ; ;     \____________________________/
    `_/          ´ ´ 
      " -------´-´  

首先,我们将决定是否有3个重复数字或2个重复数字。翻转硬币来决定!尾巴为3,头部为2.我们将此结果称为ͷ。

取出用0(零)绣制的袋子片刻。

现在从你面前的9个麻袋中随机挑一些ͷ(2或3)个宝石。记住,你不能从0开始,这就是我们暂时删除它的原因!永远地从你的麻袋行中取出刚刚从麻袋中取出的麻袋。你不能再选择这个了。将0(零)麻袋放回线上。

将您刚刚挑选的一块宝石放在自己面前。手拿ͷ-1。

现在重复此操作,直到手中有9块石头:

  

选择一个随机袋,从中挑出一块石头并将其握在手中。从袋子里取出袋子   线。

在这个过程结束时,你手上会有9块石头,一块在你自己面前。把你手中的那些洗牌。把它们放在你自己面前的一条直线上,紧挨着你面前的石头。

你将以10个数字结束,ͷ重复相同的数字,不会从零开始,而你面前的剩余麻袋只是沿路移除麻袋的副作用。< / p>

答案 1 :(得分:1)

如果首先使用规则尝试制作你想要的东西然后构建其余部分呢。

这是一个可能的想法

使用第一条规则

One of the digits has to be in the String 2 times and one has to not be there at all.

  1. 创建一个LinkedList,然后将数字1到9添加到其中。

  2. 生成0-8(列表索引范围)之间的随机数,使用索引从列表中检索一个值(如删除它)然后将其添加到String中数字不是0.

  3. 将0添加回列表,以便可以在其他地方使用。

  4. 现在在LinkedList中剩下9个数字,第一个数字为非零,并且已经按照步骤2在String变量中。从这里,生成LinkedList索引范围内的另一个随机数。无论这个数字是什么,将它从LinkedList中删除,将它添加两次到ArrayList。

  5. 现在,LinkedList中还有8个数字,字符串中有1个非零数字。和ArrayList中的3个数字,表示序列中总共有4个数字被确认为正确。您必须再获得6个数字才能完成它。到目前为止它看起来像这样。

  6. String sequence => "4"

    ArrayList beingBuilt => [2, 6, 6]

    LinkedList available => [1, 3, 4, 5, 7, 8, 9, 0]

    1. 似乎你只能拥有10个数字,通过LinkedList循环6次,使用随机数来获取随机索引,将其从LinkedList中删除,将其添加到ArrayList。
    2. 在此之后,ArrayList应该有9个数字,您可以将其随机化以使其更随机,然后将其转换为String并附加到序列的末尾。你的规则现在应该得到满足。

      为了让它更随机你可以操纵你从LinkedList中拔出数字的方法,以及你可以改变它的最后一条规则。由于删除速度较快,我使用了LinkedList,我确实考虑过使用一个集合,但可能需要做更多的工作来处理被映射到集合中实际存在的数字的随机数索引。

      只是一个想法

答案 2 :(得分:0)

如果您不太关心性能,那么最简单的方法就是生成随机的数字列表,并根据您的条件检查它们,直到您得到一个有效的数据。最好将过滤作为数字,然后在最后转换为字符串,而不是使用正则表达式。

public String getRandomInts() {
    Random random = new Random();
    int[] ints;
    do {
        ints = random.ints(10, 0, 10).toArray();
    } while (!meetsCriteria(ints));
    return Arrays.stream(ints).mapToObj(String::valueOf).collect(Collectors.joining(""));
}

private boolean meetsCriteria(int[] ints) {
    if (ints[0] == 0) {
        return false;
    }
    if (frequency(ints, 0) == 1 
            && frequency(ints, 1) == 8
            && frequency(ints, 2) == 1) {
        return true;
    }
    if (frequency(ints, 0) == 2 
            && frequency(ints, 1) == 7
            && frequency(ints, 3) == 1) {
        return true;
    }
    return false;
}

private int frequency(int[] ints, int count) {
    return (int) IntStream.range(0, 10)
            .filter(n1 -> Arrays.stream(ints).filter(n2 -> n1 == n2).count() == count)
            .count();
}

答案 3 :(得分:0)

这个想法是:首先生成一个随机字符串,每个字符串为0-9,而不是从0开始,然后:1。将另一个数字替换为另一个或2.将两个数字替换为另一个。

import java.util.Random;

public class Main {
    public static void main(String[] args) {
        System.out.println(generateRandomString());
        System.out.println(generateRandomString());
    }


    public static String generateRandomString() {
        String alphabet = "0123456789";
        String result = "";
        Random random = new Random();
        // build a random string construct will 0-9 and each digital appear once
        for (int i = 0; i < 10; i++) {
            int index = random.nextInt(alphabet.length());
            if (i == 0) { // first cannot be 0
                index = random.nextInt(alphabet.length() - 1) + 1;
            }
            String c = alphabet.substring(index, index + 1);
            result += c;
            alphabet = alphabet.replace(c, "");
        }
        return random.nextInt(2) == 0 ? shuffle1(random, result) : shuffle2(random, result);
    }

    // One of the digits has to be in the String 2 times and one has to not be there at all.
    private static String shuffle1(Random random, String result) {
        int from = random.nextInt(10);
        int to = random.nextInt(9) + 1;
        while (from == to) {
            to = random.nextInt(9) + 1;
        }
        result = result.replace(result.substring(to, to + 1), result.substring(from, from + 1));
        return result;
    }

    // One digit has to be there 3 times, and 2 other digits can not be there at all
    private static String shuffle2(Random random, String result) {
        int from = random.nextInt(10);
        int to1 = random.nextInt(9) + 1;
        int to2 = random.nextInt(9) + 1;
        while (from == to1) {
            to1 = random.nextInt(9) + 1;
        }
        while (from == to2 || to2 == to1) {
            to2 = random.nextInt(9) + 1;
        }
        result = result.replace(result.substring(to1, to1 + 1), result.substring(from, from + 1));
        result = result.replace(result.substring(to2, to2 + 1), result.substring(from, from + 1));
        return result;
    }

}