以最小长度递归地分割字符串的所有方法

时间:2018-02-14 22:33:35

标签: java string recursion

我偶然发现了这个简洁的递归函数。

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]]

这可以在不事后循环结果的情况下完成吗?首先不要创建不符合最小值的元素。

1 个答案:

答案 0 :(得分:0)

是的,应该有可能。但是,恕我直言,由于以下原因,您的算法难以理解和修改:

  • 它修改列表(append.set(0, aps);)的内容
  • 它连接字符串,因此,如果跳过处理1个长度的字符串,则会中断迭代。

我无法更改它,所以...我以自己的方式重写了算法:

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());