繁体   English   中英

递归字符串函数(Java)

[英]Recursive String Function (Java)

我正在尝试设计一个函数,该函数基本上如下:

字符串s =“ BLAH”;

将以下内容存储到数组中:等等啦啊啊啊啊啊啊啊

所以基本上我所做的就是一次从每个字母中减去一个字母。 然后一次减去两个字母的组合,直到剩下2个字符。 将这些世代中的每一个存储在一个数组中。

希望这是有道理的,

杰克

你是怎么得到“ al”的? 这些也混在一起吗?

我将创建一个HashSet来保存所有排列并将其传递给递归方法。

void foo(HastSet<String> set, String string) {
    if (string.length < 2) // base case
        return
    else {
        // add the string to the hashset
        set.add(string);

        // go through each character
        for (int i = 0; i < string.length; i++) {
            String newString = s.substring(0,i)+s.substring(i+1);
            foo(set, newString);
        }
    }
}

那就是您在乎独特性。 如果没有,您可以使用向量。 无论哪种方式,您都可以使用toArray取回阵列。

这是@voodoogiant答案的优化。 基本上,我想将单词构建任务推迟到递归的基本情况下。 这样,您可以使用StringBuilder扩展单词。 因此,基本上,递归操作是打开和关闭布尔数组的位,该位表明是否在下一个单词中必须使用某个字母。

一段时间没有编写Java代码了,如果某些内容无法编译,请原谅我。

void buildWords(String baseWord, boolean[] usedLetters, HashSet<String> words, int index){
    if (index == baseWord.length()){
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < index; i++){
            if (usedLetters[i])
                builder.append(baseWord.characterAt(i));
        }
        words.add(builder.toString());
    }
    else{
        usedLetters[index] = true;
        buildWords(baseWord, usedLetters, words, index+1);
        usedLetters[index] = false;
        buildWords(baseWord, usedLetters, words, index+1);
    }
}

您必须注意的事项:

  1. 这可以构建空字符串(如果数组的所有位置为false)。
  2. 这可以构建重复的单词(如果baseWord具有连续的重复字符),我不记得HashSet在添加重复的键时是否引发异常。
  3. 不记得在字符串末尾附加一个char的StringBuilder方法是否称为“ append”,但是您知道了。
  4. 不记得输出构建的字符串的StringBuilder方法是否是“ toString”,但是您也可以理解。

您确实不需要递归来执行此操作。 这是一个迭代算法:

    String master = "abcd";
    final int L = master.length();

    List<String> list = new ArrayList<String>();
    list.add(master);
    Set<String> current = new HashSet<String>(list);
    for (int i = L-1; i >= 2; i--) {
        Set<String> next = new HashSet<String>();
        for (String s : current) {
            for (int k = 0; k < s.length(); k++) {
                next.add(s.substring(0, k) + s.substring(k + 1));
            }
        }
        list.addAll(current = next);
    }
    System.out.println(list);
    // prints "[abcd, abc, abd, bcd, acd, ac, ad, ab, bc, bd, cd]"

本质上,这本质上是广度优先的搜索 您从current包含String mastercurrent集开始。 然后在i每次迭代中,遍历for (String s : current)并生成next集合,方法是从s删除每个可能的字符。

有效的Java 2nd Edition:项目25:首选列表而不是数组 ,但是如果您坚持要存储在String[] ,则可以在末尾执行以下操作。

    String[] arr = list.toArray(new String[0]);

也可以看看

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM