【问题标题】:How do I get not just all substrings, but all POSSIBLE substrings of a string?如何不仅获得所有子字符串,而且获得字符串的所有 POSSIBLE 子字符串?
【发布时间】:2015-08-04 18:29:06
【问题描述】:

我有以下代码:

public class Application {

public static void main(String[] args)
{
    String source = "Testing";
    go(source);
}

public static void go(String source)
{
    for (int i = 0; i < source.length(); i ++)
    {
        for (int j = i + 1; j <= source.length(); j++)
        {
            System.out.println(source.substring(i, j));
        }
    }
}

}

当我运行这段代码时,我得到以下输出:

T
Te
Tes
Test
Testi
Testin
Testing
e
es
est
esti
estin
esting
s
st
sti
stin
sting
t
ti
tin
ting
i
in
ing
n
ng
g

这很棒 - 但它实际上并不是我想要的。我还希望能够获得作为该单词子字符串的所有可能字符串。

如gist、set、tie等

我意识到我的代码在这方面是错误的,但我也不确定如何扩展它以实现我想要的!

感谢任何帮助!

【问题讨论】:

  • 您想要字符串中所有可能随机选择的字符的所有可能排列吗? (gist、set、tie 甚至不是子串的排列)
  • Gist、set、tie 等不是“Testing”的子字符串。它们是“测试”的一些排列的子串。你想要给定单词的所有排列的所有可能的子串吗?那将是一大堆字符串!如果我的快速计算是正确的(计算重复),则“测试”一词的 141120 个字符串。
  • 所有可能的排列 - 现在只需阅读下面的回复 :)
  • @marstran 我得到 13700,实际测量生成序列的长度。
  • @WillNess 我也明白了。我的快速计算没有distinct 子句。

标签: java string recursion


【解决方案1】:

通过这个排列函数(取自Generating all permutations of a given string):

public static List<String> permutation(final String str) {
    return permutation("", str);
}

private static List<String> permutation(final String prefix, final String str) {
    final List<String> list = new ArrayList<>();

    final int n = str.length();
    if (n == 0) {
        list.add(prefix);
    } else {
        for (int i = 0; i < n; i++) {
            list.addAll(permutation(prefix + str.charAt(i),
                                    str.substring(0, i) + str.substring(i + 1, n)));
        }
    }

    return list;
}

还有这个子字符串函数(只是改变了你函数的返回类型):

public static List<String> substrings(final String source) {
    final List<String> list = new ArrayList<>();
    for (int i = 0; i < source.length(); i++) {
        for (int j = i + 1; j <= source.length(); j++) {
            list.add(source.substring(i, j));
        }
    }
    return list;
}

我使用 Java 8 流制作了这个解决方案:

public static void main(String[] args) {
    Stream.of("Testing")
          .flatMap(s -> permutation(s).stream())
          .flatMap(s -> substrings(s).stream())
          .distinct()
          .forEach(System.out::println);
}

【讨论】:

  • 我希望我理解这个解决方案!它有效,但我真的不明白为什么,我没有得到我们需要的前缀......
  • @Slippy 在计算排列时只需要前缀。您只需调用List&lt;String&gt; permutation(final String str) 方法即可获取排列。
  • 谢谢 - 很抱歉花了这么长时间才将其添加为最佳答案,我真的不确定它是如何工作的! :)
【解决方案2】:

您想要所有字符子集的所有排列。

使用番石榴:

Set<Character> chars = Sets.newHashSet(Chars.asList(source.toCharArray()));
Set<String> r = Sets.powerSet(chars).stream()
                    .flatMap(cs -> Collections2.permutations(cs).stream()
                                     .map(l -> String.valueOf(Chars.toArray(l))))
                    .collect(Collectors.toSet());

【讨论】:

  • 看起来不错,但您正在使用集合删除重复字符。
  • 没错,也许其他库更适合这项工作
  • Guava 也有一个 MultiSet。也许可以使用?
【解决方案3】:

试试这个:效率不高,但似乎可行

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class MainClass {

    private static Set<String> store = new HashSet<String>();

    public static void main(String args[]) {

        doAll("testi");

        Iterator<String> it = store.iterator();

        while (it.hasNext()) {

            System.out.println(it.next());

        }

    }

    public static void doAll(String str) {

        for (int i = 0; i < str.length(); i++) {

            String doingString = str.substring(i, str.length());
            permuteString("", doingString);

        }

    }

    public static void permuteString(String beginningString, String endingString) {

        if (endingString.length() <= 1) {


            store.add(beginningString + endingString);
            doAll(beginningString);
        }

        else
            for (int i = 0; i < endingString.length(); i++) {
                try {
                    String newString = endingString.substring(0, i)
                            + endingString.substring(i + 1);

                    permuteString(beginningString + endingString.charAt(i),
                            newString);
                } catch (StringIndexOutOfBoundsException exception) {
                    exception.printStackTrace();
                }
            }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-06-03
    • 1970-01-01
    • 2012-09-14
    • 1970-01-01
    • 2021-03-30
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    相关资源
    最近更新 更多