私はあなたの更新に似た考えをいくつか持っていましたが、何も除外しないので、おそらくあなたは私のものよりもエレガントになるでしょう
文字列内のすべての大文字の一種のバイナリ テーブルを作成することから始めました (小文字は触れられないので無視できます)。
非常に単純な例から始めて、上に向かって進んでください。バイナリ テーブルでは、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();
}
}