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ビット整数に対応できるよりも多くのシンボルが必要な場合は、いつでもbigintを使用できます。

コメントへの回答:

人々がコメントしているように、このアプローチには先行ゼロに関する問題があります。明らかな解決策は、Nがベースで、nがシンボルの数である文字列に変換する前に、整数表現に値N ^(n + 1)を追加することです。これは、001ではなく1,1,2を1001に変換する効果があり、事実上ゼロを許可します。

しかし、これには、当初の意図どおりに実際には単純なソリューションになるには複雑すぎるソリューションになるという欠点があります。

于 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
  • すべてBのsから1sへのロールオーバー
  • あなたがより少ないものを見つけるかB、あなたが壁にぶつかるまで(pos == -1
  • 壁にぶつかったら挿入0
  • で文字をインクリメントpos
于 2010-03-24T13:31:38.000 に答える
1

あなたのタスクは組み合わせタスクであると思います。組み合わせアルゴリズムを実装して、指定された数値(1、2、3、4)の一意の組み合わせを見つけ、このアルゴリズムを1から望ましい長さまで繰り返す必要があります。

そして、ここで使用できるJavaの特定の機能を想像することはできません。いくつかのイテレータになります。

アルゴリズムの説明については、アルゴリズムを読んで、nからk個の要素のすべての組み合わせを返すことをお勧めします。

于 2010-03-24T13:21:00.693 に答える
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 に答える