Java 使用递归方法查找字符串中的字数

Java 使用递归方法查找字符串中的字数,java,recursion,Java,Recursion,我想使用递归方法(java)计算字符串中的字数 到目前为止,我写了这段代码 public static int CountWords(String sen) { int count = 0; int i = sen.indexOf(" "); if (sen.isEmpty()) { return 0; }else if (i == sen.indexOf(" ")) { return count++; }

我想使用递归方法(java)计算字符串中的字数

到目前为止,我写了这段代码

public static int CountWords(String sen) {
    int count = 0;
    int i = sen.indexOf(" ");
    if (sen.isEmpty()) {
        return 0;
    }else 
        if (i == sen.indexOf(" ")) {
      return count++;
   }
  //sen.substring(0,sen.indexOf(" ")-1);
    count++;
    return count + CountWords(sen.substring(i + 1));
}
调用该方法时,我总是得到0
有人能帮我运行这段代码吗

问题在于如何使用
indexOf
。您正在将
i
设置为调用
indexOf
的结果,然后查看它是否等于在具有相同参数的相同字符串上调用
indexOf
的结果。测试结果
i==sen.indexOf(“”)
将始终为真。这就是为什么你总是得到0

String#indexOf
如果未找到要查找的字符,则返回-1
indexOf
在这里非常方便

此外,您不应该需要局部计数变量。在这里引入一个变量只会使代码更难阅读,因为读者必须四处寻找,找出它的价值

假设您的输入在单词之间始终只有一个空格,则可以这样做:

public static int countWords(String s) {
    if (s.isEmpty()) return 0;
    if (s.indexOf(" ") == -1) return 1;
    return 1 + countWords(s.substring(s.indexOf(" ") + 1));
}
对于单词之间的多个空格,您可以检查空格并跳过:

public static int countWords(String s) {
    if (s.isEmpty()) return 0;
    if (s.indexOf(' ') == -1) return 1;
    if (s.charAt(0) == ' ') return countWords(s.substring(1));
    return 1 + countWords(s.substring(s.indexOf(' ') + 1));
}

我认为这应该行得通:

public static int countWords(String sen) {
    int i = sen.indexOf(" ");
    if (sen.isEmpty()) {
        return 0;
    } else if (i == -1) {
        return 1;
    } else return 1 + countWords(sen.substring(i + 1));
}
关于正在发生的事情的一些注意事项:

  • Java命名约定规定,方法名称应以小写字母开头
  • 如果(i==sen.indexOf(“”)是redunant,则行
    ,您刚才将
    i
    指定为前面的行,因此它将始终计算为true
  • 因此,您的递归永远不会被调用。您需要更改它,以便如果
    sen
    不是空的并且至少包含一个以上的空格,
    countWords
    sen
    减去第一个单词来调用自己
  • 这将有助于:


    此方法使用不带空格的字符串作为基本大小写。然后它删除字符串中第一个空格之前的所有内容并递归

    它处理空字符串的特殊情况以及传递给方法的字符串以空格开头的情况

    public static int CountWords(String sen) 
    {   int i = sen.indexOf(" ");
        if(sen.isEmpty()) return 0;          // special case
        if(i == -1) return 1; // base case
    
        if(i != 0)
            return 1 + CountWords(sen.substring(i+1));
        else
            return CountWords(sen.substring(1));
    }
    

    虽然它可以工作,但这不是递归编码的好方法。您基本上是以迭代方式编写的,然后忽略循环,将迭代准备工作抛出窗口,并调用递归。请参阅我的代码或@Nathan Hughes,了解如何通过递归优雅地实现这一点。我同意,但优化不是问题所在。此代码只是OP中代码的修复。无论问题是什么,答案都应努力显示问题的良好解决方案,遵守编码标准和最佳实践。即使你在OP中“修正”了代码,你的答案对未来的读者也没有什么价值。如果你输入
    字符串
    “奶牛跳过了月亮\\”
    ,那么你得到7作为计数。OP应该考虑改进算法来检测这一点。如果<代码>字符串是NULL,也可能需要一个防御性检查。@ STATICX:这是一个很好的建议,但是我觉得我需要为OP留下一些东西。看起来核心问题不是递归,所以这是我的答案。非常感谢您的回复。实际上现在看看OP的代码,我认为问题在于没有正确地获取终止条件。如果
    sen
    为空,则获取
    索引(“”
    )是没有意义的。如果将该检查向下移动到递归调用
    countWords
    ,则基本上会得到@NathanHughes的答案。如果
    字符串
    为空,可能还需要进行防御检查。@staticx True。我已经修改了OP的密码,那一定是错过了。对于空字符串,性能影响应该可以忽略不计,但你是对的,它并不像它可能的那么漂亮。我不确定我是否同意防御性
    null
    检查。我不喜欢防御性地
    null
    检查是否没有明显合适的值。我想这取决于一个空字符串有多少个单词的定义:0,或者询问是一个错误。如果你对一个空
    字符串调用
    isEmpty
    ,你会得到一个
    NullPointerException
    。请不要发布答案让其他人查看你的代码。建议你保存
    sen.indexOf(“”)
    由于您的代码最多使用局部变量三次,所以请按建议进行编辑。
    public static int CountWords(String sen) 
    {   int i = sen.indexOf(" ");
        if(sen.isEmpty()) return 0;          // special case
        if(i == -1) return 1; // base case
    
        if(i != 0)
            return 1 + CountWords(sen.substring(i+1));
        else
            return CountWords(sen.substring(1));
    }