获取特殊数字列表的算法

时间:2014-09-17 15:15:15

标签: java algorithm math

我试图在java中找到一个算法来获取一个特殊的数字列表。我试着在代码中写下自己的想法,但我觉得我的大脑开始融化......也许你可以帮助我。

算法应该给我一个所有数字的列表:

  • 具有可选择的长度

  • 只有数字在可选范围内

  • 每个号码出现一次或更少

因此,如果我将长度设置为3,将数字范围设置为0-4,则应如下所示:

012
013
014
021
023
024
031
032
034
041
042
043
102
103
...

我知道这不是我不知道的事情的问题,但我已经用这个算法度过了一个永恒,我的大脑开始受到伤害。也许我只是想错了路......

2 个答案:

答案 0 :(得分:1)

Base X Numeral Systems!

您可以将生成{...} x 的组合解释为 count in base X

您的问题,改写:枚举基数为X的数字,最高为 n 数字

的最高数字

Naïve刺:

for(int i = 0; i < Math.pow(5, 3); i++) {
    System.out.println(Integer.toString(i, 5));
}

现在,一些观察结果:

  • 你的例子以“012”开头,我假设你实际上是指“000”
  • 示例中的 base 是“4 + 1 = 5”
  • 一般情况下的 base 是“b - a + 1”,其中范围是{a..b}
  • 通常用于表示基数X中的数字的符号阿拉伯数字 0 ..(X-1)
  • 您在数字系统中使用的符号阿拉伯数字,从 a b < / LI>
  • 数字没有前导零,数字的字符串表示
  • 基数X中的最大长度n为 X n - 1
  • 您无法自定义字符串填充,因此请将 width 设置为 n 并使用 替换''

要生成字符串列表:

  1. 找到您的号码系统的 base
  2. 0到X n -1
  3. 计数
  4. 生成每个数字的基础X表示
  5. a 添加到生成的代表中的所有符号
  6. 使用 a
  7. 填充左侧的字符串

    代码!

    public static void main(String[] args) {
        for(String s : generate(3, 0, 4)) {
            System.out.println(s);
        }
    }
    
    private static List<String> generate(int n, int a, int b) {
        List<String> numbers = new ArrayList<>();
        int base = b - a + 1;                        // (1)
        for(int i = 0; i < Math.pow(base, n); i++) { // (2)
            String s = Integer.toString(i, base);    // (3)
            s = substituteSymbols(s, a);             // (4)
            s = String.format("%" + n + "s", s);     // (5)...
            s = replacePadding(a, s);                // ...(5)
    
            numbers.add(s);
        }
        return numbers;
    }
    
    private static String substituteSymbols(String s, int a) {
        char[] digits = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        for(int c = 0; c < digits.length; c++) {
            int val = Character.getNumericValue(digits[c]) + a;
            sb.append(Character.forDigit(val, Character.MAX_RADIX));
        }
        return sb.toString();
    }
    
    private static String replacePadding(int a, String s) {
        return s.replace(' ', Character.forDigit(a, Character.MAX_RADIX));
    }
    

    <强> 注意:

    • 你也可以坚持天真的刺伤并丢弃包含少于 a
    • 的数字的字符串
    • 强大的解决方案应该处理无效的参数
    • 通用解决方案不应假设alphanumeric符号
    • 由于所有新的字符串
    • ,此解决方案将产生不必要的垃圾
    • 如果基数高于Character.MAX_RADIX,将使用基数10

答案 1 :(得分:0)

您的代码应该像

public static void main (String[]args) {
    int totalNumbers=10, max=50,min =20;
    Random rand = new Random();
    Set<Integer> integers = new HashSet<Integer>();
    while(integers.size()<totalNumbers){
        integers.add(randomNumberGenerationInRange(rand, max, min));
    }
    for(Integer eachInteger: integers){
        System.out.println(String.format("%05d", eachInteger));
    }
}

private static int randomNumberGenerationInRange(Random rn,int maximum, int minimum) //This is where I'm trying to find LCM of 2 numbers
{
    int n = maximum - minimum + 1;
    int i = rn.nextInt() % n;
    return minimum + i;
}

注意String.format("%05d", eachInteger)是将前导零添加到数字中...如果您将5到3的所需输出转换为问题将会实现。使用Set是为了没有重复。