【问题标题】:In a recursive way, how do I count the number of words in a char array in java?以递归方式,如何计算java中char数组中的单词数?
【发布时间】:2018-05-28 14:44:31
【问题描述】:

我的项目是用递归的方式统计一个char数组的字数。

//Code:
public static int countWords(char[] array) {
    if (array == null)
        throw new IllegalArgumentException("The received array is null");

    char[] array_new = trimLeadingSpaces(array);

    //Arrays.copyOfRange(array_new, idxFirstSpace(array_new, 0), array_new.length);

    if(idxFirstSpace(array_new, 0) == 0)
        return 0;

    if(idxFirstSpace(array_new, 0) == array_new.length)
        return 1;

    return 0;
}

}

我以前有两种方法来获取 char[] 中的第一个空格:trimLeadingSpaces(char[] array)(返回一个 char[];例如,我们有一个类似 [abc] 的 char[],它返回 [abc ]) 和另一个函数知道第一个 ' ' 的第一个索引:idxFirstSpace(char[] array, int currentIdx) 并返回一个 int。 我的问题出在 countWords() 方法中。

// test method coundWords
    test_coundWords("abc"); // = 1
    test_coundWords("  abc  "); // = 1
    test_coundWords(" abc  def"); // = 2
    test_coundWords(" abc def d"); // = 3
    test_coundWords("a a  def  d   g "); // = 5
    test_coundWords("   "); // = 0
    test_coundWords(""); // = 0
    test_coundWords(null); // = Erro: The received array is null

控制台:

coundWords (abc) = 1
coundWords (  abc  ) = 2 //HERE IS THE PROBLEM
coundWords ( abc  def) = 2
coundWords ( abc def d) = 3
coundWords (a a  def  d   g ) = 5
coundWords (   ) = 0
coundWords () = 0
coundWords (null) = Erro: The received array is null

我无法更改方法并将 char[] 更改为字符串。它必须只适用于 char 数组。

【问题讨论】:

  • 如果你尝试拆分你的 char 数组怎么办?
  • 无法将char数组改成字符串
  • 那么对于" abc ",我是否正确理解您的代码返回2 而不是1?如果是这样,您是否调试过您的代码,尤其是当trimLeadingSpaces() 返回一个空数组或idxFirstSpace() 返回数组中没有空间时会发生什么?
  • 尝试实现类似trimLeadingSpaces(array);的方法,但去掉结尾空格
  • 我也不能这样做@vincrichaud

标签: java arrays recursion


【解决方案1】:

如果您对递归解决方案感兴趣(我们不谈论性能),那么您的代码几乎是正确的。这是修改示例:

public static int countWords(char[] array) {
    if (array == null)
        throw new IllegalArgumentException("The received array is null");

    char[] array_new = trimLeadingSpaces(array);

    if (array_new.length == 0)
        return 0;

    int nextSpacePosition = idxFirstSpace(array_new, 0);
    int count = 1;

    if (nextSpacePosition > 0 && nextSpacePosition < array_new.length)
        count += countWords(Arrays.copyOfRange(array_new, nextSpacePosition, array_new.length));

    return count;
}

P.S. 绝对清楚,我使用了trimLeadingSpaces()idxFirstSpace() 的以下实现:

private static char[] trimLeadingSpaces(char[] arr) {
    String str = new String(arr);
    while (str.length() > 0 && str.charAt(0) == ' ')
        str = str.substring(1);
    return str.toCharArray();
}

private static int idxFirstSpace(char[] arr, int currentIdx) {
    return new String(arr).indexOf(' ', currentIdx);
}

【讨论】:

    【解决方案2】:

    我不会在这里使用递归,而只是在保持少量状态的同时遍历字符数组:

    public static int countWords(char[] array) {
        boolean isSpace = true;
        int count = 0;
    
        for (int i=0; i < array.length; ++i) {
            if (array[i] != ' ' && isSpace) {
                ++count;
                isSpace = false;
            }
            else if (array[i] == ' ') {
                isSpace = true;
            }
        }
    
        return count;
    }
    

    Demo

    这里的基本思想是我们跟踪我们何时击中了一个空格字符,当发生这种情况时,我们在击中单词的开头(即单个非空格字符)时将计数加一。请注意,此空格标志开始时设置为 true,因为数组中的第一个字符可能是单词的开头。

    【讨论】:

    • 这将是更有效的方法,但由于 OP 似乎受到一些限制(我假设是出于学习目的),因此使用递归可能是其中之一。
    • 这是我必须做的...这是递归方式,但谢谢
    • @Thomas 对这个问题使用递归与我处理它的方法相去甚远。
    • 完全正确,正如我所说(并且 OP 已确认)似乎设置了使用递归,即手头的任务没有办法解决。
    • @Thomas Stack Overflow 不仅仅是给出一个家庭作业问题的答案,它是关于最佳的答案。这里最好的答案可能是基于字符数组构造一个String,然后使用字符串函数。下一个最佳答案,如果我们真的被字符数组困住,可能就是我上面写的。递归排在第三位,真正遇到这个问题的人可能不想要递归解决方案。
    【解决方案3】:

    您的问题是在这里使用array.lengthreturn 1 + countWords(Arrays.copyOfRange(array_new, idxFirstSpace(array_new, 0), array.length - 1));

    输入 " abc " array_new 最终长度为 0,但 array 长度仍为 2(因为传递了一个包含 2 个空格的数组)。因此,终止符 \0 将根据 Arrays.copyOfRange() 上的 JavaDoc 添加:

    范围(to)的最终索引,必须大于或等于from,可能大于original.length,这种情况下'\u000'被放置在索引更大的副本的所有元素中大于或等于 original.length - 从。

    因此,您会将新数组 ['\0'] 算作另一个词。把array.length改成array_new.length就可以了。

    请注意,在使用字符串时不应发生这种情况,或者在使用调试器单步执行代码时至少应弹出(对于有问题的输入,您需要输入 3 次 countWords(),而不是仅输入 2 次)。

    【讨论】:

      猜你喜欢
      • 2016-06-04
      • 1970-01-01
      • 1970-01-01
      • 2013-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多