2

我想对以下元素进行循环:

[1,2,11,12,21,22,111,112,121,122,....,222222]

或者例如

[1,2,3,11,12,13,21,22,23,31,32,33,111,112,113,... 333333333]

我怎样才能用Java制作它?在我的特殊情况下,我使用 4 位数字(1、2、3、4),最后一个数字的长度可以是 1 到 10。

我设法用 Python 和 PHP 做到了。在第一种情况下,我使用列表而不是列表。我从 [[1],[2],] 开始,然后为列表的每个元素添加 1 和 2,所以我得到 [[1,1],[1,2],[2,1],[2 ,2]] 等等:

nchips = sum(chips)
traj = [[]]
last = [[]]    
while len(last[0]) < nchips:
    newlast = []
    for tr in last:
        for d in [1,2,3,4]:
        newlast.append(tr + [d])
    last = newlast
    traj += last

当我在 PHP 中执行此操作时,我使用了以 3 为底的数字。但这是一个棘手且不优雅的解决方案。

    for ($i=-1; $i<=$n; $i+=1) {

    if ($i>-1) {
        $n5 = base_convert($i,10,5);
        $n5_str = strval($n5);
        $tr = array();
        $found = 0;
        for ($j=0; $j<strlen($n5_str); $j+=1) {
        $k = $n5_str[$j];
        if ($k==0) {
            $found = 1;
            break;
        }
        array_push($tr,$k);
        }
        if ($found==1)
        continue;
    } else {
        $tr = array();
    }
}

用Java可以轻松完成吗?

4

4 回答 4

5

这看起来很像用给定基数中的数字计数。(您的示例的基数为 2 和 3)您可以使用 Integer.toString 轻松地将整数转换为给定基数的字符串,并将该字符串的字符映射到符号。例子:

Integer.toString(6, 2) -> "011"

将此字符串映射到字符数组,然后将该数组映射到您的符号。在您的情况下,这将是:'0' -> 1 和 '1' -> 2。

这不是最有效的解决方案,但它让 Integer.toString 完成繁琐的工作,让您进行简单的数组转换。

要反过来转换,您可以从数组转换为字符串,然后使用 Integer.parseInt 再次提取 int 表示。

如果您需要执行算术运算(我猜主要是 ++ 和 -- 循环的前一个和下一个元素),请在整数上执行它们并根据需要来回转换。

免责声明:我有一段时间没有用 java 编码了,所以方法和类名可能是关闭的。

编辑:如果您需要比 32 位和 64 位整数更多的符号,您总是可以使用 big int 。

回复评论:

正如人们评论的那样,这种方法存在前导零的问题。显而易见的解决方案是在转换为字符串之前将一些值 N^(n+1) 添加到整数表示中,其中 N 是基数,n 是符号数。这将具有将 1,1,2 转换为 1001 而不是 001 有效地允许零的效果。

但这有一个缺点,即成为一个过于复杂的解决方案,实际上无法像最初预期的那样成为简单的解决方案。

于 2010-03-24T13:18:20.060 回答
2
public class Cycle {
    static void advance(StringBuilder sb, int B) {
        int pos = sb.length();
        while (--pos != -1 && sb.charAt(pos) == '0' + B) {
            sb.setCharAt(pos, '1');
        }
        if (pos == -1) {
            sb.insert(++pos, '0');
        }
        sb.setCharAt(pos, (char) (sb.charAt(pos) + 1));
    }

    public static void main(String args[]) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < 20; i++) {
            advance(sb, 3);
            System.out.println(sb);
        }
    }
}

推进如下:

  • 从右到左 ( --pos)
  • 将所有 s 翻转B1s
  • 直到你找到小于B或碰壁的东西(pos == -1
  • 如果你撞到墙上,插入0
  • 增量字符在pos
于 2010-03-24T13:31:38.000 回答
1

如果您不关心生成顺序(我的意思是它会首先产生 1;11;111,然后再产生 1;2;3)使用这个:

public static void gen(int level) {
    if (level > 0) {
        for (int i = 0; i < level; i++)
            System.out.print(arr[i] + " ");     
        System.out.println();
    }

    if (level == 10)
        return;

    for (int i = 1; i <= 4; i++) {
        arr[level] = i;
        gen(level + 1);
    }
}

public static void main(String[] args)  {
    gen(0);
}

但是,如果您关心订单,请使用:

private static int top;
private static int[] arr = new int[10]; 

public static void gen(int level) {
    if (level == top) {

        for (int i = 0; i < level; i++)
            System.out.print(arr[i] + " ");
        System.out.println();

        return;
    }

    for (int i = 1; i <= 4; i++) {
        arr[level] = i;
        gen(level + 1);
    }
}

public static void main(String[] args)  {
    for (top = 1; top <= 10; top++)
        gen(0);
}
于 2010-03-24T13:18:11.957 回答
1

我相信您的任务是一项组合任务,您应该实施组合算法来找到给定数字 (1,2,3,4) 的唯一组合 - 并将该算法从 1 迭代到所需长度。

而且我无法想象您可以在这里使用 Java 的哪些特定功能。这将是一些迭代器。

对于算法的讨论,我建议您阅读Algorithm to return all combination of k elements from n

于 2010-03-24T13:21:00.693 回答