1

String の 1 つまたは複数の BIG 文字を削除することによって可能なすべての一意の順列を生成する必要がありますが、小さな文字は変更されません。

入力例:

AalAADBdBBDkCeCCA

次に、可能なすべての順列を生成する必要があります

  • 1 つの BIG 文字を 1 回または複数回削除する
  • 1 から n 個の BIG 文字の除去を組み合わせ、それぞれを 0 から m 回除去します (n = 入力内の直接文字の数、m = 文字の出現回数)。
  • 小さい文字はそのままに

つまり、2 番目または 3 番目 (FIXED! 最初は 1 番目と 2 番目に書いた) A が削除されても違いはありません。もちろん、最初または最後の A を削除すると違いが生じます。

順列の例:

AalAADBdBBDkCeCCA // original input also counts as permutation
AalAADBdBB kCeCCA // last D removed
 alAAD dBBDkCeCCA // first A and first B removed
Aal  D dBBDkCeC A  // second and third A removed, first B and last C removed

これが役立つ場合に備えて、グアバを使用しています。プレーンな Java ソリューションでも問題ありません。

この種の順列の名前と、一意の順列の合計量を示す数式があれば、順列アルゴリズムの結果を (少なくとも順列の正しい量に関して) 検証できる場合にも興味があります。

この例は縮小された問題です。入力は、マージされた文字列ではなく、文字のリストまたはその他の事前に解析された形式として既に利用可能であると想定できます。

これに関するヒントをありがとう!

アップデート:

解決策を見つけたと思います。フィードバックを歓迎します。アイデア: 各 BIG 文字のインデックス (位置) を抽出します。それらをセットにして、このセットのパワーセット P を作成します。これにより、可能な削除のすべての順列が得られます (たとえば、1,2 と 2,1 の重複を含み、1 = 2 = 同じ BIG 文字の場合)

4

1 に答える 1

1

私はあなたの更新に似た考えをいくつか持っていましたが、何も除外しないので、おそらくあなたは私のものよりもエレガントになるでしょう

文字列内のすべての大文字の一種のバイナリ テーブルを作成することから始めました (小文字は触れられないので無視できます)。

非常に単純な例から始めて、上に向かって進んでください。バイナリ テーブルでは、0 は文字をそのままにしておくことを意味し、1 は文字を削除することを意味します。

例: A の文字列 (または aaaAa などの大文字が 1 つだけの任意の文字列) 2 つの順列

A
0
1

AB (または 2 つの大文字 aaaAaBbb の文字列) の場合 4 つの順列

AB
00
10
01
11

ABC 8順列の場合

ABC
000
100
010
110
001
101
011
111

ABCD 16順列の場合

ABCD
0000
1000
0100
1100
0010
1010
0110
1110
0001
1001
0101
1101
0011
1011
0111
1111

これらは 2^1、2^2、2^3、2^4 2^numberOfUppercaseCharacters であることがわかります。

これにより、重複の問題を削除せずに順列の総数が得られます。各文字位置が文字でオフになり、出力文字列をセットに保存することでループするブルート フォース アプローチをエレガントに実装できません。セット内にあるため、重複は追加されません。

入力文字列を解析して、各大文字のインデックスを取得します

上記のバイナリ テーブルでは、ABC を文字列内のインデックス位置に置き換えることを概念的に考えています。

そう

文字列 aaAbbBb には、インデックス 2 と 5 (0 ベースのインデックス) があります。

A B
_ _
0 0
1 0
0 1
1 1

になる

2 5
_ _
0 0
1 0
0 1
1 1

したがって、最大 2^numOfUppercase までの 2 進数の表現を取り、関連する値を削除すると、機能するはずです。以下のサンプルには、文字列と大文字のインデックス リストがハードコーディングされていることに注意してください。少なくとも、解決策を試して確認するものがあります。

このアプローチの上限については考えていないことに注意してください。順列の大きなバイナリ表現として、大文字の長い文字列で失敗する可能性があります。

そのサンプルはこちら:

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;


public class StringProcessing {


public static void main(String[] args) {
    // TODO Auto-generated method stub
    StringProcessing sp = new StringProcessing();
    sp.setUpProcessing();

}

public void setUpProcessing() {
    String input = "aaABCDcs";

    //Populate with indexes of Uppercase letters (loop though each char and check if [A-Z])
    ArrayList<Integer> indexes = new ArrayList<Integer>();
    indexes.add(2);
    indexes.add(3);
    indexes.add(4);
    indexes.add(5);

    Set<String> permutationStore = new HashSet<String>();
    BigInteger permutations = BigInteger.valueOf(2).pow(indexes.size());  //2^numOfUppercaseChars


    int maxSize = getMaxLength(permutations); //Need this for padding binary with 0

    for (BigInteger index = BigInteger.ZERO; index.compareTo(permutations) < 0;  index = index.add(BigInteger.ONE)) {
        String binary = index.toString(2);
       // System.out.println(permutations + " " + index + " " + binary + ", for string: " + input); //NumOf Permutations, currentPermutation, binaryRepresentation

        int lastIndex = binary.length() -1;
        StringBuilder currentString = new StringBuilder(input);
        String permutationString = process(lastIndex, binary, currentString, indexes, maxSize);
        permutationStore.add(permutationString);
        System.out.println(permutations + " " + index + "    " + binary + ", for string: " + input + ", Stored: " + permutationString);
    }

    System.out.println("");
    for(String s : permutationStore) {
        System.out.println(s);
    }

}

public int getMaxLength(BigInteger permutations) {
   BigInteger zeroBased = permutations.subtract(BigInteger.ONE);
   return  zeroBased.toString(2).length();
}

public String process(int lastIndex, String binary, StringBuilder currentString, ArrayList<Integer> indexes, int maxSize) {
    int indexFound = binary.lastIndexOf('1', lastIndex);

    if (indexFound == -1) {
        return currentString.toString();
    }
    int padding =  maxSize - binary.length(); //Add leading "0's" to binary 

    int index = indexFound + padding;
    int charPos = indexes.get(index);

    currentString.deleteCharAt(charPos);
    process(indexFound-1, binary, currentString, indexes, maxSize);

    return currentString.toString();
}

}
于 2013-08-22T19:33:57.140 に答える