我偶然发现了这个简洁的递归函数。
static ArrayList<ArrayList<String>> recursive(String str) {
System.out.println(str);
ArrayList<ArrayList<String>> result = new ArrayList<>();
if (str.length() == 1) {
result.add(new ArrayList<>());
result.get(0).add(str);
return result;
}
for (ArrayList<String> list : recursive(str.substring(1, str.length()))) {
ArrayList<String> append = new ArrayList<>(list);
String aps = str.substring(0, 1) + append.get(0);
append.set(0, aps);
ArrayList<String> add = new ArrayList<>(list);
String ads = str.substring(0, 1);
add.add(0, ads);
result.add(append);
result.add(add);
}
return result;
}
如果你给它arg&#34; haus&#34;:
,它会返回[[haus], [h, aus], [ha, us], [h, a, us], [hau, s], [h, au, s], [ha, u, s], [h, a, u, s]]
现在我无法弄清楚如何为每个部分实现最小长度,并且不能完全了解函数的功能。
如果我将最小长度设置为2,我想要的输出是:
[[haus], [aus], [ha, us], [us], [hau], [au]]
这可以在不事后循环结果的情况下完成吗?首先不要创建不符合最小值的元素。
答案 0 :(得分:0)
是的,应该有可能。但是,恕我直言,由于以下原因,您的算法难以理解和修改:
append.set(0, aps);
)的内容我无法更改它,所以...我以自己的方式重写了算法:
static List<List<String>> recursive(String str) {
List<List<String>> list = new ArrayList<>();
for (int i = 0; i < str.length(); i++) {
recursive(list, str, i);
}
return list;
}
static void recursive(List<List<String>> list, String str, int index) {
if (index == 0) {
List<String> stringList = new ArrayList<>();
addToList(stringList, str);
list.add(stringList);
return;
}
List<List<String>> newList = recursive(str.substring(index));
String pref = str.substring(0, index);
for (List<String> ls : newList) {
List<String> stringList = new ArrayList<>();
addToList(stringList, pref);
addToList(stringList, ls.toArray(new String[ls.size()]));
if (!stringList.isEmpty()) {
list.add(stringList);
}
}
}
static void addToList(List<String> list, String... strings) {
Stream.of(strings)
.filter(s -> s.length() > 1)
.forEach(list::add);
}
它为haus
提供此结果:
[[haus], [aus], [us], [au], [ha, us], [hau]]
是我想的。
最后一点:此后可以过滤掉长度为1的字符串:
List<List<String>> outputList = recursive("haus").stream()
.map(List::stream)
.map(stringStream -> stringStream.filter(str -> str.length() > 1))
.map(stringStream -> stringStream.collect(Collectors.toList()))
.filter(ls -> !ls.isEmpty())
.collect(Collectors.toList());