首先,我首先要说英语不是我的第一语言所以我为任何不好的解释道歉。
我想知道如何使用这么多不同的订单获取String的每个子字符串。在你告诉我之前已经问过这个问题之前,我想说几乎我看到的这个任务的每个代码实现都没有重复。但是我说我有一个字符串“环境”,我希望每个子字符串包括“ment”,“met”,“ten”,“net”,“note”,“more”等等,我将如何实现这个?
这是我写的功能。
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;
}
当我运行此功能时
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
这只是我想要的一小部分。我希望函数能够在每个顺序中获得子串。例如,如果我希望它包含像“net”,“ten”,“never”e.t.c这样的字符串,因为它们都是“环境”一词的子串。为实现这一目标,我必须对我的功能做出哪些改变?
另外,由于我是Java初学者,我想知道如果我的代码写得很好,我可以对代码做出哪些更改,使其表现更好,看起来更好,并遵循常见的Java编码约定。< / p>
提前致谢
答案 0 :(得分:2)
1)生成所有子串(你已经得到了那个部分)
2)为每个子字符串生成所有它的排列 - 您可以使用位向量递归或迭代地执行它(这里已经显示了如何做到这一点,快速谷歌搜索也将给你一些提示)
3)将所有内容添加到最终列表中,这将为您提供已有的内容,反转版本以及所有其他排列
例如&#34; abc&#34;你会得到:
- a(1 char,1 permutation)
- ab(substring)
- ba(substring permutation)
- abc(substring)
- bca(substring permutation)
- bac(substring permutation)
- acb(substring permutation)
- cab(substring permutation)
- cba(substring permutation)
请注意,计算可能需要一些时间,当字符串为N时,它有N!排列,你将为每个子字符串调用它,所以N次将产生O(N * N!)时间复杂度。
正如@ PM77-1指出的那样,如果我们的字符串有像abcabc这样重复的子串,这可能会做很多不必要的工作。在这种情况下,在每次新迭代之前,您可以检查给定的子字符串是否已经在集合中(是的,您将结果列表更改为具有O(1)查找的集合)并且如果它已经存在则跳过它。
答案 1 :(得分:1)
在this other question的帮助下,我把它放在一起。
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;
}
除非该单词包含两次该字母,否则不会重复使用该单词中的字母 在这种情况下会有双打 它没有使用递归,因此堆栈溢出不会成为问题。