【问题标题】:Using recursion to find a character in a string使用递归在字符串中查找字符
【发布时间】:2014-05-16 08:53:05
【问题描述】:

我正在尝试查找字符串中第一次出现的字母。例如,苹果中的 p 应该返回 1。这是我所拥有的:

// Returns the index of the of the character ch
public static int indexOf(char ch, String str) {

    if (str == null || str.equals("")) {
        return -1;
    } else if(ch == str.charAt(0)) {
        return 1+ indexOf(ch, str.substring(1));
    }

    return indexOf(ch, str.substring(1));
}

它似乎没有返回正确的值。

【问题讨论】:

标签: java string recursion


【解决方案1】:

你的尝试很好,但还不够。这是基于您的正确实现:

public static int indexOf(char ch, String str) {
    // Returns the index of the of the character ch

    if (str == null || str.equals("")) {
        // base case: no more string to search; return -1
        return -1;
    } else if (ch == str.charAt(0)) {
        // base case: ch is at the beginning of str; return 0
        return 0; 
    }

    // recursive step
    int subIndex = indexOf(ch, str.substring(1));

    return subIndex == -1 ? -1 : 1 + subIndex;
}

您的尝试有两个问题:

else if 部分,您找到了角色,因此正确的做法是停止递归,但您仍在继续。

在您的最后一个 return 语句中,您需要将 1 添加到递归调用(如果最终找到该字符),作为累积总索引号的一种方式。

【讨论】:

  • 我本来打算投票,但注意到你的逻辑至少有一个缺陷。如果你尝试一个不在字符串中的字母,你只会得到最后一个字母的索引。
  • @PaulSasik 看起来你和我同时注意到了这一点。现在应该修好了。
  • 酷。 +1 和其他一些词
  • @JLRishe +1 为您的递归步骤。我会说真的很聪明。在递归步骤中,我在 C++ 中执行“return 1+indexOf(s.substr(1,s.length()),c)”,除了 Paul Sasik 指出的情况外,效果很好。
【解决方案2】:

首先:递归有两大支柱,Base CaseGeneral Case

Base Case(终止点)是 Recursion 终止的地方,而 General Case 顾名思义是程序继续执行的地方直到找到 Base Case

你可以试试这个例子,其中count 是一个全局变量static

public static int indexOf(char ch, String str)
{
  // Returns the index of the of the character ch
  if (str == null || str.Equals(""))     //Base Case
  {
     if (count != 0)
     {
        if(str.Length == 0)
           return -1;  
        return count;
     }
     else
        return -1;          
  }
  else if (ch == str.CharAt(0))          //Base Case  
     return 1 + count; 
  count++;
  return indexOf(ch, str.Substring(1));  //General Case
}

【讨论】:

  • 为此使用静态变量不是一个好主意。这也有一个错误,如果字符串不包含请求的字符,则会产生完全错误的结果。
  • @JLRishe 按照您的指示,我已经修复了“字符不存在的情况”,并且我使用静态只是因为我不希望更改用户函数的原型(即使用额外的参数),无论如何感谢您的 cmets。
【解决方案3】:

如果我们必须使用递归,那么试试这个:

class RecursiveFirstIndexOf {

public static void main(String[] args) {
    System.out.println(indexOf('p', "apple", 0));
}

static int indexOf(char c, String str, int currentIdx) {

    if (str == null || str.trim().isEmpty()) {
        return -1;
    }

    return str.charAt(0) == c ? currentIdx : indexOf(c, str.substring(1), ++currentIdx);

}}

【讨论】:

  • 这是一个问题,不是答案
  • 我的意思是 indexOf 已经被 Java 提供了,那么为什么不直接使用它而不是编写方法来做同样的事情呢?
  • 我知道,但问题是:“使用递归”而不是任何内置方法。无论如何,这不是一个问题。也许是评论。
  • 递归查找字符串中字母索引的唯一原因是练习递归。这就是关键词:练习。 OP 可能只是在学习 Java,这是家庭作业、实验室作业或类似的学术活动。
【解决方案4】:

这是另一个变体。您可以稍微修改函数以传递下一个要检查的索引,而不是调用 substring。请注意,递归是从索引 0 开始的。(您实际上可以从任何索引开始。还有一些错误检查以防找不到字母。在苹果中查找 x 将返回 -1。)

public static void main(String []args){  
    System.out.println("Index: " + indexOf('e', "apple", 0));
    System.out.println("Index: " + indexOf('x', "apple", 0));
    System.out.println("Index: " + indexOf('p', "Mississippi", 3));
    System.out.println("Index: " + indexOf('p', "Mississippi", 908));
}

public static int indexOf(char ch, String str, int idx) {
    // check for garbage data and incorrect indices
    if (str == null || str.equals("") || idx > str.length()-1) 
        return -1;

    // check to see if we meet our condition
    if (ch == str.charAt(idx)) 
        return idx;

    // we don't match so we recurse to check the next character
    return indexOf(ch, str, idx+1);
}

输出:

指数:4 指数:-1 指数:8 指数:-1

【讨论】:

  • idx = indexOf(ch, str, ++idx); 这让我感到畏缩。为什么不return indexOf(ch, str, idx + 1)
  • @JLRishe:我刚刚发布了一个关于你的畏缩的编辑,因为你的评论登陆了。 :-)
  • 你确实做到了。 :) 我仍然认为idx + 1 在这里要好得多。没有理由增加 idx 变量。
  • @JLRishe:+1 好点。 idx+1 更具可读性和直观性,尤其是对于新手而言。不知道为什么我做了前缀的事情。我猜是大脑上的 for 循环。
【解决方案5】:

为什么不直接做呢?

public static void main(String[] args) {
    String str = "abcdef";
    for (int idx = 0; idx < str.length(); idx++) {
        System.out.printf("Expected %d, found %d\n", idx, indexOf(str.charAt(idx), str, 0));
    }
    System.out.printf("Expected -1, found %d\n", indexOf(str.charAt(0), null, 0));
}

public static int indexOf(char ch, String str, int index) {
    if (str == null || index >= str.length()) return -1;
    return str.charAt(index) == ch ? index : indexOf(ch, str, ++index);
}

输出:

Expected 0, found 0
Expected 1, found 1
Expected 2, found 2
Expected 3, found 3
Expected 4, found 4
Expected 5, found 5
Expected -1, found -1

【讨论】:

  • 当人们显然认为variable + 1 字符太多时,我永远无法理解为什么他们使用++variable
【解决方案6】:

我会给你一些提示:

  1. 找到这封信后,无需进一步递归。此外,请考虑在这种情况下您应该返回什么。
  2. 什么时候递归,还要考虑函数应该返回什么。
  3. 如果递归调用返回-1,有什么特别需要做的吗?

【讨论】:

    猜你喜欢
    • 2016-10-02
    • 2021-12-10
    • 2015-05-13
    • 2014-02-19
    • 1970-01-01
    • 2021-09-20
    • 2017-06-13
    • 2016-01-27
    • 2016-05-20
    相关资源
    最近更新 更多