【问题标题】:Which is a more legitimate recursive helper method?哪个是更合法的递归辅助方法?
【发布时间】:2012-12-09 15:23:41
【问题描述】:

我的任务是为一个测试用户输入的回文的类编写方法。该类必须有一个递归方法,并且该方法必须调用一个辅助方法来删除空格、标点符号并忽略大小写。

我有两个工作类来做这些事情,但我想知道哪种结构效果更好,哪种辅助方法实际上符合辅助方法的描述。

这是第一堂课:

public class RecursivePalindrome
{

public boolean Palindrome(String s)
{
    return PalindromeHelper(s);
}

public boolean PalindromeHelper(String s)
{
    String a = s.toLowerCase();    //Converts any capital letters to lowercase beforte analyzing the string
    a = a.replaceAll(" ", "");    //Removes any and all spaces in the string

    for(int i = 0; i < a.length(); i++)     //Removes punctuation by using isLetter method from Character Class
    {
        if(Character.isLetter(a.charAt(i)) == false)
            a = a.replace(a.substring(i, i+1), "");
    }

    if(a.length() == 0 || a.length() == 1)
        return true;
    else if(a.charAt(0) == (a.charAt(a.length() - 1)))
        return PalindromeHelper(a.substring(1, a.length() - 1));
    else
        return false;
}
}

第二个:

public class Recurs
{

public boolean Palindrome(String s)
{
    String l = PalindromeHelper(s);

    if(l.length() == 0 || l.length() == 1)
        return true;
    else if(l.charAt(0) == (l.charAt(l.length() - 1)))
        return Palindrome(l.substring(1, l.length() - 1));
    else
        return false;
}

public String PalindromeHelper(String s)
{
    s = s.toLowerCase();    //Converts any capital letters to lowercase before analyzing the string
    s = s.replaceAll(" ", "");    //Removes any and all spaces in the string

    for(int i = 0; i < s.length(); i++)     //Removes punctuation by using isLetter method from Character Class
    {
        if(Character.isLetter(s.charAt(i)) == false)
            s = s.replace(s.substring(i, i+1), "");
    }
    return s;
}
}

【问题讨论】:

  • 第二个实现。显然适合“一种删除空格、标点符号和忽略大小写的辅助方法”
  • 有没有办法让第二个更有效率?每次回文重复时,它都会调用辅助方法,这在第一次调用辅助方法后是不必要的。
  • 然后只需将 PalindromHelper() 调用下方的所有内容拉入一个新方法(例如 PalindromRecurse())并递归调用它。

标签: java methods recursion helper


【解决方案1】:

我会这样写。

class RecursivePalindrome
{

    public boolean Palindrome(String s)
    {
        //Think about using a stringbuilder instead of a string.

        String a = s.toLowerCase(); // Converts any capital letters to lowercase
                                    // beforte analyzing the string
        a = a.replaceAll(" ", ""); // Removes any and all spaces in the string

        for (int i = 0; i < a.length(); i++) // Removes punctuation by using
                                             // isLetter method from Character
                                             // Class
        {
            if (Character.isLetter(a.charAt(i)) == false)
                a = a.replace(a.substring(i, i + 1), "");
        }
        return validatePalindrome(a);
    }

    public boolean validatePalindrome(String s)
    {
        if (s.length() == 0 || s.length() == 1)
            return true;
        else if (s.charAt(0) == (s.charAt(s.length() - 1)))
            return PalindromeHelper(s.substring(1, s.length() - 1));
        else
            return false;
    }
}

【讨论】:

    【解决方案2】:

    在我们开始编写代码之前有几件事...

    “帮助”方法通常被称为 utility 方法,它是一段 无状态 代码 - 是无状态的:

    • 应该声明为static

    遵守 java 命名约定是个好主意,所以:

    • 方法名称以小写字母开头
    • 布尔方法以 is 开头,如果这样做是合理的

    所以,你的“帮助”方法应该是这样的:

    private static String clean(String s) {
        return s.toLowerCase().replaceAll("[^a-z]", "");
    }
    

    此方法可以完成您的方法所做的所有事情,但只需要一小部分代码。

    因为你的 main 方法也是无状态的,所以它也应该是静态的,除非因为类层次结构或接口等需要它是实例方法。

    因此,您的主要方法应该是:

    public static boolean isPalindrome(String s) {
         return isPalindromeClean(clean(s));
    }
    
    private static boolean isPalindromeClean(String s) {
        return s.length() < 2 || a.endsWith(s.charAt(0)) && 
            isPalindromeClean(l.substring(1, l.length() - 1));
    }
    

    同样,一行代码完成所有工作。需要注意的几点:

    • 您的代码每次递归调用“干净”方法,但通过创建第二个方法,我避免了这种低效率。
    • 使用endsWith() 既简单又明确条件
    • 使用封装逻辑的单个简单返回语句

    整个类变成下面这样,只有 3 行实际代码。

    public class Recurse {
    
        public static boolean isPalindrome(String s) {
             return isPalindromeClean(clean(s));
        }
    
        private static boolean isPalindromeClean(String s) {
            return s.length() < 2 || a.endsWith(s.charAt(0)) && 
              isPalindromeClean(l.substring(1, l.length() - 1));
        }
    
        private static String clean(String s) {
            return s.toLowerCase().replaceAll("[^a-z]", "");
        }
    }
    

    我什至不会费心使用 clean 方法 - 我会像这样简单地内联它:

    public static boolean isPalindrome(String s) {
        return isPalindromeClean(s.toLowerCase().replaceAll("[^a-z]", ""));
    }
    

    但是,如果你被设置了一个任务,说你必须创建它,那么你就会被它困住。不过我会展示这个替代方案。

    通常,代码越优雅,代码就越少。

    【讨论】:

      猜你喜欢
      • 2014-05-03
      • 1970-01-01
      • 2020-06-06
      • 2016-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-05
      • 2011-10-26
      相关资源
      最近更新 更多