【问题标题】:Java recursive method for counting words用于计数单词的Java递归方法
【发布时间】:2013-02-11 11:12:44
【问题描述】:

首先我应该说这是一个让我感到困惑的作业,我已经纠正了讲师的一个问题:/

无论如何,我已经创建了一个使用布尔值、while 循环和计数器计算单词的方法。

但是我需要了解如何将其转化为一种计算字符串中单词数量的递归方法,一个单词由一个或多个空格分隔。

countWords(" hello this is an example", 0); // returns 5

如您所见,唯一的参数是 countWords(String s, int i) 使其变得更加困难。

此外,在该方法中,我仅限于使用这三种方法 s.charAt(0)、s.substring(1) 和 s.equals("") 再次使它更让人头疼:)

这是我使用 while 循环编写的非递归方法:

public static int countWords(String s) {
    int words = 0;
    boolean spaceBefore = true;
    boolean spaceCurrently = false;
    while(true) {
        if (s.equals(""))
            return words;

        if (s.charAt(0) == ' ')
            spaceCurrently = true;
        else
            spaceCurrently = false;

        if (spaceBefore && !spaceCurrently)
            words++;        

        spaceBefore = spaceCurrently;
        s = s.substring(1);
    }
}

【问题讨论】:

  • 发布您的第一个方法。以及您为递归代码尝试过的任何代码。
  • 提示:字数=空格数+1。字数 = 1 + 字符串中第一个空格后的字数。
  • @MrSmith42 a word is delimited by one or **many** spaces
  • Spoon 先生要求的发布方法
  • @fvu:好的,但这不会改变算法思想。

标签: java recursion count words


【解决方案1】:

因为这是家庭作业,所以我不会给你代码。但我会向你解释解决方案。看看你是否可以从中重建代码。

在方法中,首先删除行首和行尾的空格,因为我们想忽略它。为此使用trim() 方法。接下来检查字符串是否为空字符串 (""),就像您在代码中所做的那样。如果是,则返回零,因为空字符串不包含任何单词,否则在无限循环 (while (true)) 中检查以下条件:

  • 创建一个变量来保存当前索引,该索引不是循环本地的,而是方法本地的。对于无限循环的每次迭代,检查当前字符(使用charAt() 方法)是否不是空格以及索引是否小于字符串的长度。如果此条件为真,则递增索引变量。
  • 如果不是,检查索引变量是否等于字符串的长度。如果是,则返回 1,因为这意味着我们已经到达了字符串的最后一个单词。
  • 如果不是,则返回 1 的总和以及计算单词的方法,从 index 的当前值递归调用子字符串。

这应该会为您带来价值。如果您仍然无法做到,请告诉我,我会给您来源。

EDIT好吧,如果你不能使用String的trim方法,你可以像这样为自己写一个。我相信它不会违反您的任何要求:

private String trim(String str) {
    int beginIndex = 0;
    int endIndex = str.length() - 1;

    while (true) {
        if (str.charAt(beginIndex) == ' ') {
            beginIndex++;
        } else if (str.charAt(endIndex) == ' ') {
            endIndex--;
        } else {
            break;
        }
    }

    return str.substring(beginIndex, endIndex);
}

编辑2如果你也不能使用length(),那么修改上面这行代码int endIndex = str.length() - 1;' toint endIndex = getLength(str) - 1;`,使用下面的代码来计算长度.

private int getLength(String str) {
    int length = 0;

    while (true) {
        try {
            str.charAt(length++);
        } catch (StringIndexOutOfBoundsException e) {
            break;
        }
    }
    return --length;
}

编辑 3 由于问题是这样的 PITA,因此很难用语言解释。代码如下:

private int countWords(String searchString) {
    int index = 0;
    boolean beginning = true;       // to check if it's the beginning of the line

    if (searchString.equals("")) {
        return 0;
    } else {
        while (true) {
            try {
                if (searchString.charAt(index) != ' ') {
                    beginning = false;
                    index++;
                } else {
                    if (!beginning) {
                        return 1 + countWords(searchString.substring(++index));
                    } else {
                        return countWords(searchString.substring(++index));
                    }
                }
            } catch (StringIndexOutOfBoundsException e) {
                if (!beginning) {
                    return 1;
                } else {
                    return 0;
                }
            }
        }
    }
}

这将帮助您只使用您被允许使用的方法来实现您想要的。

【讨论】:

  • 我不能使用 trim() 方法。
  • 如果不想使用Stringtrim(),可以使用上面的代码。
  • 我也不能使用 .length() 大声笑,我特别说我只能使用我的问题中所述的三种方法?
  • 虽然我全心全意地认为必须允许使用 length(),但我已经编辑了我的解决方案以纳入您的请求。
  • 大声笑,我的讲师非常挑剔,希望我们能深入到核心,除了我说的三个之外,不使用任何 API 方法,我们也不允许计算字符串的长度 XD
【解决方案2】:

我不会直接发布代码,因为这是你的任务,但这里有一些指导。

字符串中的单词数是当前单词+字符串其余部分的单词数。 由于您一次只能处理一个字符,因此您可以这样想:

  • 有一个参数告诉你是否在一个词中
  • 如果 s.charAt(0) 是一个空格并且您在一个单词中,那么您将增加计数器并将 inWord 设置为 false
  • 如果 s.charAt(0) 是一个字母并且您不在一个单词中,那么您将 inWord 设置为 true
  • 使用更新的计数器和 s.subString(1) 进行递归并更新 inWord

然后你用 0, s, false 开始一切

想象一下将循环转换为递归,就像将变量从循环外移到方法参数中一样。

我希望这不会太混乱。

【讨论】:

  • 我不能将布尔值作为参数。
  • 如果一次只能移动一个角色,则需要将状态保持在某个地方。如果您可以断言单词之间只有一个空格,则不需要状态。
  • 这就是麻烦,如果我尝试在方法中创建一个布尔值,它也总是会重置回我最初设置的值,我需要一种使用重置的方法。
【解决方案3】:

鉴于这是作业,我不会直接给你答案。

如果方法调用自身的机制,则递归。显然,如果一个方法不确定地执行此操作,您最终会得到一个 stackoverflow 异常,因此您需要某种退出条件,该方法停止调用自身。

这是一个示例 - 假设您想编写一个乘法方法,该方法接受两个数字并将它们相乘,但您只能使用加法和减法。

public int multiply(int value1, int value2) 
{
  if (value1 > 1) 
  {
    int remaining = value1 - 1;
    return value2 + multiply(remaining, value2);
  }
  else 
  {
    return value2;
  }
}

这里方法调用自身,直到将 value2 添加到自身 value1 次,此时它返回堆栈。

你可以做一些与你的字数统计类似的事情——继续调用该方法,传递一个从第一个空格到字符串末尾的子字符串,直到字符串中没有更多空格,此时返回堆栈。

【讨论】:

    猜你喜欢
    • 2016-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多