在Java中计入基数2,3,4等并输出所有排列

tre*_*ker 5 java binary combinations permutation counting

我想在Java中编写一个函数,它将整数作为输入,并输出每个可能的数字排列,直到整数.例如:

F(1)

0

f(2)应输出:

00 01 10 11

f(3)应输出:

000 001 002 010 011 012 020 021 022 100 .... 220 221 222

也就是说,它应该输出数字0,1,2的数字的所有27个排列.

f(4)应输出0000 0001 0002 0003 0010 ... 3330 3331 3332 3333

f(5)应输出00000 00001 ... 44443 44444

我一直试图解决这个问题,但似乎无法解决如何做到这一点,并不断被我需要多少循环弄糊涂.有谁知道如何解决这个问题?提前致谢.

old*_*inb 3

只需计算并转换即可。我在这里写了一些应该对早期答案有所帮助的内容。

\n\n
\n

这应该是一个比较容易解决的问题。

\n\n

本质上,您只是计算字符串集\ xce\xa3^5,其中\xce\xa3 = { 0, 1, 2 }

\n\n
static Iterable<String> strings(final int radix, final int digits) {\n  return new Iterable<String>() {\n\n    public Iterator<String> iterator() {\n      return new Iterator<String>() {\n\n        private final String pad;\n        {\n          final StringBuilder buf = new StringBuilder(digits);\n          for (int n = digits; n >= 0; --n) {\n            buf.append(\'0\');\n          }\n          pad = buf.toString();\n        }\n\n        private final int hi = (int) Math.pow(radix, digits);\n        private int cursor;\n\n        public boolean hasNext() {\n          return cursor < hi;\n        }\n\n        public String next() {\n          final String rsl = Integer.toString(cursor++, radix);\n          return pad.substring(0, digits - rsl.length()) + rsl;\n        }\n\n        public void remove() {\n          throw new UnsupportedOperationException();\n        }\n      };\n    }\n  };\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

...可以按如下方式使用:

\n\n
for (final String val : strings(3, 5)) {\n  System.out.println(val);\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

基本上,我们生成区间[0, 3^5)中的数字,其中3是我们的基数,5是我们所需的字符串长度,然后将数字转换为三进制形式。0变为000003^5变为100000。您还必须注意不要使用太大的基数,否则结果String将包含错误的字符。

\n
\n\n
\n\n

这里的解决方案是仅仅调用strings(n, n). 请注意,根据您的基数或所需的数字长度有多大,您可能希望改为使用longBigInteger

\n\n

另外,由于它依赖于Integer.toString,请确保记住以下警告......

\n\n
\n

如果基数小于Character.MIN_RADIX或大于,则使用Character.MAX_RADIX基数代替。10

\n
\n\n

Character.MIN_RADIX您可以看到is2MAX_RADIXis的值36。如果您使用超出此范围的基数,它将默认为10...您将需要使用数字的自定义扩展字符集编写自己的转换。这种函数的一般形式itoa如下:

\n\n
    private static final char[] ALPHABET = { \'0\', \'1\', \'2\', \'3\', ... };\n\n    public static String itoa(int value, final int radix, int width) {\n      final char[] buf = new char[width];\n      while (width > 0) {\n        buf[--width] = ALPHABET[value % radix];\n        value /= radix;\n      }\n      return new String(buf);\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n
\n\n

下面是一个可供您使用的工作示例(请参阅ideone上的结果)。

\n\n
static Iterable<String> f(final int n) {\n  return strings(n, n);\n}\n\npublic static void main(final String[] argv) {\n  for (int n = 1; n <= 5; ++n) {\n    for (final String string : f(n)) {\n      System.out.printf("%s ", string);\n    }\n    System.out.println();\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

...产生:

\n\n
\n

0

\n\n

00 01 10 11

\n\n

000 001 002 010 011 012 020 021 022 100 101 102 110 111 ...

\n\n

0000 0001 0002 0003 0010 0011 0012 0013 0020 0021 0022 0023 0030 ...

\n\n

00000 00001 00002 00003 00004 00010 00011 00012 00013 00014 00020 00021 00022 ...

\n
\n