【问题标题】:Recursive helper method递归辅助方法
【发布时间】:2014-05-03 14:29:33
【问题描述】:

我找不到这个练习的正确解决方案,这是任务:


(数组中指定字符的出现次数) 编写递归方法 查找指定字符在数组中出现的次数。 您需要 定义以下两个方法。第二个是递归辅助方法。

public static int count(char[] chars, char ch)

public static int count(char[] chars, char ch, int high)

编写一个测试程序,提示用户在一行中输入一个字符列表, 和一个字符,并显示该字符在列表中出现的次数。


1) 只有添加另一个参数(int index)才能解决它,但是如果不添加另一个参数或使用 for 循环,我怎么能做到呢?

2) 为什么会有辅助方法?我不明白递归中辅助方法的目的。

这是我的解决方案:

package occurencesinarray;

import java.util.Scanner;

public class Start {
public static void main(String[] args){
    System.out.println("Enter few characters: ");
    Scanner scan = new Scanner(System.in);
    String s = scan.nextLine();
    char[] chars = new char[s.length()];
    for(int i = 0; i < s.length(); i++){
        chars[i] = s.charAt(i);
    }
    System.out.println("Enter desired character: ");
    char ch = scan.nextLine().charAt(0);

    System.out.println(count(chars, ch));
}

public static int count(char[] chars, char ch){
    return count(chars, ch, 0, 0);
}

public static int count(char[] chars, char ch, int high, int index){
    if(index == chars.length){
        return high;
    }
    if(chars[index] == ch){
        return count(chars, ch, high + 1, index + 1);
    } else{
        return count(chars, ch, high, index + 1);
    }
}
}

【问题讨论】:

    标签: java recursion helpermethods


    【解决方案1】:

    首先,您的辅助(递归)方法应该是private,而不是public。它需要了解它的工作原理才能正确调用它。这与良好的软件设计背道而驰,后者认为实现并不重要,只要遵守合同即可。

    第一个方法只是设置递归方法的初始条件(参数)的面向公众的外观。真正的作用是在递归方法中。

    递归(辅助)方法通常具有必须确定(和编码)的三件事:

    • 初始状态
    • 终止条件
    • 如何进入下一个状态

    初始状态通常由外观方法处理,就像您的情况一样。

    终止状态通常是方法中的第一行代码,并导致立即返回(您的情况也是如此)

    如果不满足终止条件,则可以在本地保存状态(和/或计算)以对返回值做出贡献,然后该方法使用将状态推进到下一个位置的参数调用自身。返回自调用的结果,可能与保存状态的数据相结合。

    在您的情况下,您将本地状态传递给下一次调用。不要这样做。相反,组合它:

    public static int count(char[] chars, char ch, int index) {
        // Test for terminating condition
        if (index == chars.length) {
            return 0;
        }
        // return 1 if ch matches (0 otherwise) plus count from the remaining input
        return (chars[index] == ch ? 1 : 0) + count(chars, ch, index + 1);
    }
    

    并使用索引0 调用它以启动该过程。

    【讨论】:

      【解决方案2】:

      正如 AllenKll 已经指出的那样,high 值可能应该扮演您为 index 指定的角色。您一直在计算 high 变量中出现的次数,但这种计数可以“隐藏”在递归中。

      这些用于递归的“帮助”方法的目的通常是:它们通常(至少)有一个附加参数,以某种方式描述递归已经进行了多远或还需要进行多远。作为后者的示例:您也可以使用 high 变量作为“倒计时”,通过编写

      public static int count(char[] chars, char ch)
      {
          return count(chars, ch, chars.length - 1);
      }
      
      public static int count(char[] chars, char ch, int high)
      {
          if (high == -1)
          {
              return 0;
          }
          if (chars[high] == ch)
          {
              return 1 + count(chars, ch, high - 1);
          }
          return count(chars, ch, high - 1);
      }
      

      当然,只能提供辅助方法。而不是调用

      count(chars, ch);
      

      你可以让用户打电话

      count(chars, ch, 0);
      

      但是这里的问题是这个方法可能被误用:当用户传递一个错误的值作为最后一个参数时,那么该方法将不起作用。

      注意:整个“辅助方法”只有在辅助方法是私有时才有意义。当为public 时,用户仍有可能调用错误的方法。我看到在任务描述中请求了public 修饰符,但是......当你让你的导师意识到这个缺陷时,也许你会获得一些奖励积分;-)

      【讨论】:

        【解决方案3】:
        public static int count(char[] chars, char ch)
        {
           return count(chars, ch, 0);
        }
        
        public static int count(char[] chars, char ch, int high)
        {
            int count = high;
            if chars.size()== 0
            {
               return count;
            }
            else if(chars.indexOf(0) == ch)
            {
               count++;
            }
        
            return count(Arrays.copyOfRange(charList, 1, charList.size()), ch, count);
        }
        

        【讨论】:

          【解决方案4】:

          这个怎么样:

          high代表指数

          public static int count(char[] chars, char ch, int high){
              if(high == chars.length){
                  return 0;
              }
              if(chars[index] == ch){
                  return count(chars, ch, high + 1) + 1;
              } else{
                  return count(chars, ch, high + 1);
              }
          }
          

          辅助方法是调用者不需要知道“high”参数。在另一种语言中,例如 C 中可以有默认参数,则没有必要。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2012-12-09
            • 1970-01-01
            • 2020-06-06
            • 1970-01-01
            • 2019-05-05
            • 1970-01-01
            • 2012-08-07
            相关资源
            最近更新 更多