[英]Java - Get All Permutations, Substrings and Permutations of every Substring of a String
首先,我首先要說英語不是我的第一語言,所以對於任何糟糕的解釋,我深表歉意。
我想知道如何獲得具有這么多不同順序的字符串的每一個 substring。 在你告訴我這個問題之前有人問過之前,我想說我看到的這個任務的幾乎每個代碼實現都不包含重復項。 但是假設我有一個字符串“環境”,我想要每一個 substring,包括“ment”,“met”,“ten”,“net”,“note”,“more”
這是我寫的function。
public static ArrayList<String> getAllSubstringsOfAString(String inputString)
{
ArrayList<String> allSubstrings = new ArrayList<String>();
String sub;
for(int i = 0; i < inputString.length(); i++)
{
for (int j = 1; j <= inputString.length() - i; j++)
{
sub = inputString.substring(i , i + j);
allSubstrings.add(sub);
}
}
return allSubstrings;
}
當我運行這個 function
public static void main(String[] args) throws IOException {
ArrayList<String> allSubStrings = getAllSubstringsOfAString("environment");
for (String allSubString : allSubStrings) {
System.out.println(allSubString);
}
它打印出來
e
en
env
envi
envir
enviro
environ
environm
environme
environmen
environment
n
nv
nvi
nvir
nviro
nviron
nvironm
nvironme
nvironmen
nvironment
v
vi
vir
viro
viron
vironm
vironme
vironmen
vironment
i
ir
iro
iron
ironm
ironme
ironmen
ironment
r
ro
ron
ronm
ronme
ronmen
ronment
o
on
onm
onme
onmen
onment
n
nm
nme
nmen
nment
m
me
men
ment
e
en
ent
n
nt
t
這只是我想要的一小部分。 我希望 function 能夠按每個順序獲取子字符串。 例如,如果我希望它包含像“net”、“ten”、“never” etc 這樣的字符串,因為它們都是“environment”這個詞的子字符串。 我必須對我的 function 進行哪些更改才能達到此目的?
另外,由於我是 Java 初學者,我想知道我的代碼是否寫得好,我可以對我的代碼進行哪些更改以使其性能更好,看起來更好,並遵循常見的 Java 編碼約定。
提前致謝
1)生成所有子串(你已經得到了那個部分)
2)為每個子串生成所有它的排列 - 你可以使用位向量遞歸或迭代地執行它(這里已經顯示了如何做到這一點,快速谷歌搜索也會給你一些提示)
3)將所有內容添加到最終列表中,這將為您提供已有的內容,反轉版本以及所有其他排列
例如,使用“abc”,您將獲得:
- a(1個字符,1個排列)
- ab(子串)
- ba(子串置換)
- abc(子串)
- bca(子串置換)
- bac(子串置換)
- acb(substring permutation)
- cab(子串置換)
- cba(子串置換)
請注意,計算可能需要一些時間,當字符串為N時,它有N! 排列,你將為每個子字符串調用它,所以N次將產生O(N * N!)時間復雜度。
正如@ PM77-1指出的那樣,如果我們的字符串有像abcabc這樣的重復子字符串,這可能會做很多不必要的工作。 在每次新迭代之前的情況下,您可以檢查給定的子字符串是否已經在集合中(是的,您將結果列表更改為具有O(1)查找的集合)並且如果它已經存在則跳過它。
在另外一個問題的幫助下,我把它扔到了一起。
public static void main(String[] args) {
List<String> list = perms("codes");
list.forEach(s -> System.out.println(s));
}
public static List<String> perms(String string) {
List<String> result = new ArrayList<String>();
char[] values = string.toCharArray();
for (int width = 1; width <= values.length; width++) { // for every length
int stack[] = new int[width];
for (int i = 0; i < stack.length; i++) { // start from a specific point without duplicates
stack[i] = stack.length - i - 1;
}
int position = 0;
while (position < width) {
position = 0;
StringBuilder sb = new StringBuilder();
while (position < width) { // build the string
sb.append(values[stack[position]]);
position++;
}
result.add(sb.toString());
position = 0;
while (position < width) {
if (stack[position] < values.length - 1) {
stack[position]++;
if (containsDuplicate(stack) == false)
break;
else
position = 0;
} else {
stack[position] = 0;
position++;
}
}
}
}
return result;
}
private static boolean containsDuplicate(int[] stack) {
for (int i = 0; i < stack.length; i++) {
for (int j = 0; j < stack.length; j++) {
if (stack[i] == stack[j] && i != j) {
return true;
}
}
}
return false;
}
它不會重復使用該單詞中的字母,除非該單詞包含該字母兩次。
在這種情況下會有雙打。
它不使用遞歸,因此堆棧溢出不會成為問題。
下面的程序返回所有可能的子集及其各自的排列。
public class PermutationWithSub {
public void subStrings(String string){
List<List<Character>> listList = new ArrayList<>();
listList.add(new ArrayList<>());
ArrayList<String> subStringArraylist = new ArrayList<>();
ArrayList<String> bruteList = new ArrayList<>();
for (char c:string.toCharArray()){
int size = listList.size();
for (int i=0;i<size;i++){
List<Character> temp = new ArrayList<>(listList.get(i));
temp.add(c);
listList.add(temp);
}
}
for (List<Character> characterList : listList) {
StringBuilder stringBuilder = new StringBuilder();
for (Character character : characterList) {
stringBuilder.append(character);
}
subStringArraylist.add(stringBuilder.toString());
}
for (String str:subStringArraylist){
List<List<Character>> listListChar = permute(str);
for (List<Character> listChar:listListChar){
StringBuilder stringBuilder = new StringBuilder();
for (Character character:listChar){
stringBuilder.append(character);
}
bruteList.add(stringBuilder.toString());
}
}
listList.clear();
subStringArraylist.clear();
for (String str:bruteList){
System.out.println(str);
}
}
public List<List<Character>> permute(String string){
List<List<Character>> powerSet = new ArrayList<>();
generateSet(powerSet,new ArrayList<>(),string.toCharArray());
return powerSet;
}
private void generateSet(List<List<Character>> powerSet, List<Character> temp, char[] chars) {
if (temp.size()==chars.length){
powerSet.add(new ArrayList<>(temp));
}else {
for (char aChar : chars) {
if (temp.contains(aChar))
continue;
temp.add(aChar);
generateSet(powerSet, temp, chars);
temp.remove(temp.size() - 1);
}
}
}
public static void main(String[] args) {
MyBruteForceTool myBruteForceTool = new MyBruteForceTool();
myBruteForceTool.subStrings("abcd@1234");
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.