-1

ここで順列文字列に関するすべてのメソッドを参照しましたが、近いものがありますが、それでも期待どおりに機能しませんでした。この入力から出力を生成するにはどうすればよいですか: 入力: 5, 出力: から までの文字列の組み合わせを表示aしますzzzzz。入力として 6 を入力すると、 fromaから出力されzzzzzzます。

ここに道はありますか?3 を入力すると、3 つのループで作業する必要があることがわかりました。6 つの入力は 6 つのループを意味しますが、動的ではなく静的です。つまり、3 入力で 3 ループを作成できませんでした。

これが私の現在のコードです:

String pattern = "abcdefghijklmnopqrstuvxyz";  
String s;  
for (int i = 0; i < pattern.length(); i++) {  
  for (int j = 0; j < pattern.length(); j++) {  
    for (int k = 0; k < pattern.length(); k++) {  
      s = pattern.charAt(i) + "" + pattern.charAt(j) + "" + pattern.charAt(k);  
      System.out.println(s);  
    }  
  }  
}

*編集: * 上記の私のコードは 5 の長さをまっすぐに表示します。

4

4 に答える 4

1

これは実際のプログラミングの問題ではなく、「学習演習」であると想定しています。26^6(まともな人なら、 (3 億 800 万) 行を標準出力に書き込もうとはしません ...)

だからここにヒントがあります:

  • 再帰、および StringBuilder またはchar[].

これは順列の問題ではないことも付け加えておきます。組み合わせの問題です。そして、ここではソートは行われません。むしろ、文字列は順番に生成されます。

于 2013-07-01T03:42:52.930 に答える
1

これは、相互に呼び出す 2 つのメソッドを使用した再帰パターンのサンプルです。

private String pattern = "abcdefghijklmnopqrstuvxyz";
private int numChar = 3;

public void permutateY(String prefix, int charPos, int patternPos) {
    if (patternPos>=pattern.length()) return;

    if (prefix == null) {
        permutateX(String.valueOf(pattern.charAt(patternPos)), charPos+1, 0);
    } else {
        permutateX(prefix + String.valueOf(pattern.charAt(patternPos)), charPos+1, 0);
    }
    permutateY(prefix, charPos, patternPos+1);
}

public void permutateX(String combi, int charPos, int patternPos) {
    if (charPos < numChar) {
        permutateY(combi, charPos, 0);
    } else {
        System.out.println(combi);
    }
}

ただし、@Stephen Cに完全に同意します。26 ^ 6を出力するのは正気ではありません:p

于 2013-07-01T06:12:27.990 に答える
1

まず、現在のコードが何をしているか見てみましょう:

整数ijおよびkがあり、これらはすべて 0 から始まります。整数は、文字列の最初の位置で使用する変数iの文字に対応します。pattern整数jは 2 番目の位置にk対応し、3 番目の位置に対応します。

次に、ループはijおよびの値をk次の順序で変更します。

i=0, j=0, k=0 => corresponds to "aaa"
i=0, j=0, k=1 => corresponds to "aab"
i=0, j=0, k=2 => corresponds to "aac"

これは、

i=0, j=0, k=25 => corresponds to "aaz"
i=0, j=1, k=0  => corresponds to "aba"

同様に、=25 と=25 の後、1 ずつインクリメントjし、両方を 0 にリセットします。その後、再びインクリメントを開始します。これは、199 の後に 200 を取得する 10 進数表記に似ています。kjkijkk

したがって、これを変化する長さに適用するには、変数を動的に格納する方法が必要です。これに最適なツールは整数配列です。

整数配列を想像してみてくださいint idx[]。その長さは、入力によって異なります。次のように初期化できます。

int idx[] = new int[n];//where n is the length of the generated strings

、 、などのidx整数を格納するために使用します。これらは、生成された文字列に使用される文字に対応します。たとえば、配列の長さが 6 で、値が [0,0,2,4,25,25] の場合、文字列 "aacezz" に対応します。ijkidx

可能なすべての文字列を生成するには、すべての値をidx0 (「aaaaaa」に対応) から開始し、while ループを作成します。反復ごとに、 in の値を「インクリメント」しidxて、次に生成される文字列を取得します。基本的な構造は次のようになります

while(/*has more to generate */){
    int i = n - 1;//end of the array
    //decrement i until we see idx[i] != 25 -> Need a loop here!
    //increment idx[i]
    //reset to zero everything to the right of idx[i]. -> Need another loop here!
}

私はコードを入れていないことに注意してください.Javaコメントで何が起こるべきかを説明しているだけです. 残りを埋めることができるはずです。

幸運を!

于 2013-07-01T04:24:23.780 に答える
1

これは期待どおりに機能します。しかし、Stephen C が言ったことをもう一度思い出してください。

import java.util.*;

public class Main {
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    Map<Integer, String> myMap = new HashMap<>();
    myMap.put(1, "a");
    myMap.put(2, "b");
    myMap.put(3, "c");
    myMap.put(4, "d");
    myMap.put(5, "e");
    myMap.put(6, "f");
    myMap.put(7, "g");
    myMap.put(8, "h");
    myMap.put(9, "i");
    myMap.put(10, "j");
    myMap.put(11, "k");
    myMap.put(12, "l");
    myMap.put(13, "m");
    myMap.put(14, "n");
    myMap.put(15, "o");
    myMap.put(16, "p");
    myMap.put(17, "q");
    myMap.put(18, "r");
    myMap.put(19, "s");
    myMap.put(20, "t");
    myMap.put(21, "u");
    myMap.put(22, "v");
    myMap.put(23, "w");
    myMap.put(24, "x");
    myMap.put(25, "y");
    myMap.put(26, "z");

    Scanner in = new Scanner(System.in);
    System.out.println("Enter limit here [input type: integer]\n");
    int lim = in.nextInt();
    String[] arr = new String[26 * lim];
    int i = 0;
    int j = lim;
    int k = 1;
    while (i < arr.length) {
        while (lim > 0) {
            arr[i] = myMap.get(k);
            lim--;
            i++;
        }
        lim = j;
        k++;
    }
    print_nCr(arr,arr.length, lim);
}

public static final void print_nCr(String[] arr,final int n, final int r) {
    int[] res = new int[r];
    for (int i = 0; i < res.length; i++) {
        res[i] = i + 1;
    }
    boolean done = false;
    while (!done) {
        for(int i=0;i<res.length;i++){
            System.out.print(arr[res[i]-1]);
        }
        System.out.print("\n");
        done = getNext(res, n, r);
    }
}
public static final boolean getNext(final int[] num, final int n, final int r) {
    int target = r - 1;
    num[target]++;
    if (num[target] > ((n - (r - target)) + 1)) {
        while (num[target] > ((n - (r - target)))) {
            target--;
            if (target < 0) {
                break;
            }
        }
        if (target < 0) {
            return true;
        }
        num[target]++;
        for (int i = target + 1; i < num.length; i++) {
            num[i] = num[i - 1] + 1;
        }
    }
    return false;
}

} 

編集した質問に対する回答は次のとおりです。これを試して

import java.util.*;

public class Main {
public static void main(String[] args) {
    List<String> list = new ArrayList<>();
    Map<Integer, String> myMap = new HashMap<>();
    myMap.put(1, "a");
    myMap.put(2, "b");
    myMap.put(3, "c");
    myMap.put(4, "d");
    myMap.put(5, "e");
    myMap.put(6, "f");
    myMap.put(7, "g");
    myMap.put(8, "h");
    myMap.put(9, "i");
    myMap.put(10, "j");
    myMap.put(11, "k");
    myMap.put(12, "l");
    myMap.put(13, "m");
    myMap.put(14, "n");
    myMap.put(15, "o");
    myMap.put(16, "p");
    myMap.put(17, "q");
    myMap.put(18, "r");
    myMap.put(19, "s");
    myMap.put(20, "t");
    myMap.put(21, "u");
    myMap.put(22, "v");
    myMap.put(23, "w");
    myMap.put(24, "x");
    myMap.put(25, "y");
    myMap.put(26, "z");

    Scanner in = new Scanner(System.in);
    System.out.println("Enter limit here [input type: integer]\n");
    int lim = in.nextInt();
    String[] arr;
    for(int x=1;x<lim+1;x++){
        arr= new String[26 * x];
        int i = 0;
        int j = x;
        int k = 1;
        while (i < arr.length) {
            while (x > 0) {
                arr[i] = myMap.get(k);
                x--;
                i++;
            }
            x = j;
            k++;
        }
        print_nCr(arr,arr.length, x);

    }

}

public static final void print_nCr(String[] arr,final int n, final int r) {
    int[] res = new int[r];
    for (int i = 0; i < res.length; i++) {
        res[i] = i + 1;
    }
    boolean done = false;
    while (!done) {
        for(int i=0;i<res.length;i++){
            System.out.print(arr[res[i]-1]);
        }
        System.out.print("\n");
        done = getNext(res, n, r);
    }
}
public static final boolean getNext(final int[] num, final int n, final int r) {
    int target = r - 1;
    num[target]++;
    if (num[target] > ((n - (r - target)) + 1)) {
        while (num[target] > ((n - (r - target)))) {
            target--;
            if (target < 0) {
                break;
            }
        }
        if (target < 0) {
            return true;
        }
        num[target]++;
        for (int i = target + 1; i < num.length; i++) {
            num[i] = num[i - 1] + 1;
        }
    }
    return false;
}

}
于 2013-07-01T07:43:49.810 に答える