【问题标题】:Given two Strings, determine if 1 is a substring of the other recursively给定两个字符串,递归判断 1 是否是另一个字符串的子字符串
【发布时间】:2017-01-11 08:58:10
【问题描述】:

我遇到了一些练习题,其中之一是取两个字符串并确定一个是否是另一个的子字符串。我写了我的第一个解决方案:

public static boolean isSubstring(String s1, String s2){
    String longer = s1.length() > s2.length() ? s1 : s2;
    String shorter = s1.length() < s2.length() ? s1 : s2;
    String substring;

    for(int i = 0; i < longer.length() && i + shorter.length() <= longer.length(); i++){
        substring = longer.substring(i, i + shorter.length());
        if(substring.equals(shorter))
          return true;
    }
    return false;
}

然后我记得 Java 有一个用于 String 类的 contains 方法,当时解决方案很简单。 :

public static boolean isSubstringUsingContains(String s1, String s2){
  String longer = s1.length() > s2.length() ? s1 : s2;
  String shorter = s1.length() < s2.length() ? s1 : s2;
  return longer.contains(shorter);

}

由于我正在练习并且我不太擅长递归,所以我认为我应该尝试递归解决这个问题,但我无法正确解决。我如何用递归解决这个问题,与上述解决方案相比,这里使用递归是否有任何优点/缺点。这是我尝试递归解决此问题的失败尝试:

 public static boolean isSubstringRecursive(String s1, String s2,int i){
  if(s1.length() == 0 || s2.length() == 0)
   return false;

  String longer = s1.length() > s2.length() ? s1 : s2;
  String shorter = s1.length() < s2.length() ? s1 : s2;

  if(longer.equals(shorter))
     return true;

  return isSubstringRecursive(longer.substring(i,i + shorter.length()),shorter,i + 1);


}

编辑

测试用例: 字符串 A = "蝙蝠侠" 字符串 B = "atm" 结果:真

字符串 A = "倒立" 字符串 B = "站立" 结果:真

字符串 A = "Hotsauce" 字符串 B = "ecu" 结果:错误

【问题讨论】:

  • 你有测试用例吗?
  • 递归是伪装的循环 - 您的工作代码中没有循环:为什么您认为需要递归?
  • 我建议您将startsWith 用于您的基本情况,将substring(1) 用于您的递归情况。如果较长的字符串以较短的字符串开头,那么您就完成了。否则,删除第一个字符并递归。
  • @assylias 我的第一个解决方案中有一个循环;并且递归不是我需要的东西,而是我需要学习如何正确做的东西。
  • @ElroyJetson Here's 一个很好的递归页面。它是递归应该做的核心:处理大问题(例如树),并将其分解为较小的问题(例如节点)

标签: java recursion


【解决方案1】:

我正在对您的例程进行最小的更改以使其正常工作。请参阅代码中的我的 cmets 进行解释。

/* Adding an extra argument to store the longest value constantly across multiple recursions. */
public static boolean isSubstringRecursive(String longString, String s1, String s2,int i){

  if(s1.length() == 0 || s2.length() == 0)
   return false;

  String longer = s1.length() >= s2.length() ? s1 : s2;
  String shorter = s1.length() < s2.length() ? s1 : s2;

  /* set the longString in the first iteration only */
  if(i==0)longString=longer;

  if(longer.equals(shorter))
     return true;

  /* To prevent substring to go out of boounds */
  if(i+ shorter.length() > longString.length()) return false;

  /* Use longString for substring since it holds the originally long string */
  return isSubstringRecursive(longString, longString.substring(i,i + shorter.length()),shorter,i + 1); 

}

这段代码可以在很大程度上进一步优化。但我会把这部分留给你做进一步的工作。

注意 1:正如您所说,您可以使用 String 类的 'contains' 方法轻松实现此目的。但是,在您为contains 演示的解决方案中,您实际上不必检查字符串长度。请参阅以下内容:

return s1.contains(s2) || s2.contains(s1);

注意2:你也可以使用String类的indexOf来做同样的事情。请参阅以下内容:

return (s1.indexOf(s2) != -1 || s2.indexOf(s1) != -1);

长话短说,有很多更简单的选项可以实现您的目标,因此无需选择 recursion 选项。

【讨论】:

  • 谢谢。感觉很好,我在递归的正确轨道上的某个地方。我同意这样的问题不需要它,但感谢您抽出时间来帮助我提高技能。
猜你喜欢
  • 1970-01-01
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-27
  • 2019-05-11
  • 1970-01-01
相关资源
最近更新 更多