【问题标题】:isSubstring recursive methodisSubstring 递归方法
【发布时间】:2012-10-28 20:42:08
【问题描述】:

下面是调用递归方法的代码:

if (isSubstring(str1, str2))
    System.out.println ("\"" + str1 + "\" is a substring of " +
                        "\"" + str2 + "\"");
else
    System.out.println ("\"" + str1 + "\" is not a substring of " + 
                       "\"" + str2 + "\"");

这是我目前完成的方法,几乎​​可以工作了:

public static boolean isSubstring(String str, String target)
{   
    if (target.length() == 0)
        return false;

    if (str.equals(target))
        return true;

    else     
        return (isSubstring(str, target.substring(0,target.length()-1)));            
}

所以如果str1作为“zzz”传递,str2作为“zzzabcdef”传递,那么它会返回true。但是,如果 str2 是“abczzzxx”或“abczzz”,它不会返回 true。有人有什么建议或想法吗?

【问题讨论】:

  • 你的方法可以是一行:return str.contains(target);
  • 我注意到您的if (target.length() == 0) 声明。您可能还想对 str 和 target 进行一些空检查。我喜欢使用StringUtils.isBlank() 方法;见commons.apache.org/lang/api-2.5/org/apache/commons/lang/…
  • @assylias 我想重点是用递归作为练习
  • @maasg 可能 - OP应该已经说清楚了。如果目标只是重新实现包含,那么查看源代码也可能具有指导意义。

标签: java methods recursion substring


【解决方案1】:

我遇到了一个挑战,只能用 charAt()、length() 和 substring() 编写这种函数,这是我写的,我认为它工作正常......

public static void main(String[] args)
{
    System.out.println(isSubstring("pgram", "program")); // Expected: false
    System.out.println(isSubstring("string", "substring")); // Expected: true
    System.out.println(isSubstring("zzz", "zzzabcdef")); // Expected: true
    System.out.println(isSubstring("zzz", "abczzzxx")); // Expected: true
    System.out.println(isSubstring("zzz", "abczzz")); // Expected: true
    System.out.println(isSubstring("hell", "hello")); // Expected: true
    System.out.println(isSubstring("ada", "Madam")); // Expected: true
}

public static boolean isSubstring(String str, String target)
{
    if (str.length() == 0)
        return true;

    if (target.length() == 0)
        return false;

    if (str.charAt(0) == target.charAt(0)) // "zzz", "zzzabcdef"
    {
        if (str.length() == target.length()) // "zzz", "zzz"
            return isSubstring(str.substring(1), target.substring(1));

        else if (target.length() > str.length()) // "zzz", "zzzabcdef"
        {
            boolean r1 = isSubstring(str, target.substring(0, str.length())); // "zzz", "zzzabcdef"
            boolean r2 = isSubstring(str, target.substring(1)); // Or maybe "string", "substring"

            return r1 || r2;
        }
    }

    return isSubstring(str, target.substring(1));
}

【讨论】:

    【解决方案2】:

    目前您只能从字符串末尾删除字符。您的函数可以正确调用startsWith(...)

    对于子字符串匹配,我会尝试以下算法:

    在没有匹配的情况下从主字符串中删除字符。 当两个字符串匹配时开始使用它们,直到您匹配子字符串的所有连续字符,或者直到您找到一个不匹配的字符,这将允许您提前停止。

    类似这样的:

    boolean isSubString(String s1, String s, boolean match) {
       if (s1 == "") return true; 
       if (s == "") return false;
       if ((s1.charAt(0) != s.charAt(0)) && match) return false; //failfast
       if (s1.charAt(0) == s.charAt(0)) return isSubString(s1.substring(1), s.substring(1), true);
       return isSubString(s1.substring(1), s.substring(1), match);
    }
    
    boolean isSubString(String s1, String s) {
        return isSubString(s1, s,false);
    }
    

    【讨论】:

      【解决方案3】:

      试试

      public static boolean isSubstring(String str, String target) {
                  System.out.println("target :" + target);
                  if (str.equals(target))
                      return true;
                  else if (str.length() > target.length())
                      return false;
                  else
                      return (isSubstring(str, target.substring(1, target.length())))
                              || (isSubstring(str,
                                      target.substring(0, target.length() - 1)));
              }
      

      这应该递归地尝试来自目标的所有子字符串。

      【讨论】:

        【解决方案4】:

        是的——基本上你的递归方法总是去掉最后一个字符,然后递归,直到它得到一个空字符串或值等于到第一个字符串。

        这意味着它可以找到第一个字符串的唯一可能位置是目标字符串的开头,这意味着它实际上是一个startsWith 方法。

        一个效率极低但我认为应该可行的选择是尝试将一个字符从前面尝试从末尾(独立地)取出一个字符:

        return isSubstring(str, target.substring(0, target.length() - 1))
            || isSubstring(str, target.substring(1));
        

        【讨论】:

        • @maasg:我怀疑是这样......这当然很可怕。
        猜你喜欢
        • 2014-03-04
        • 2012-10-22
        • 1970-01-01
        • 2021-10-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多