【问题标题】:boolean function that contains "bab"包含“bab”的布尔函数
【发布时间】:2014-03-02 20:41:55
【问题描述】:

我怎么会有一个递归布尔方法来检查它是否包含bab。我有这个,但我想递归地做。

public static boolean hasBAB(String str) {
      if (str.length() < 3) return false;
      if (str.substring(0,3).equals("bab"))
        return true;
      else
        return false;
    }

【问题讨论】:

  • 如果String"bab" 开头或者是否包含它?为什么需要递归来查看它是否以它开头?你只需要在String开头的地方打勾。
  • 如果以"bab"开头,递归做就没有意义了。
  • 如果它包含在任何地方
  • @AnupamSaini 不是,因为它不是递归的。请参阅我的答案下方的 cmets。

标签: java recursion


【解决方案1】:
public static boolean hasBAB(String str) {
  if (str.length() < 3) return false;
  if (str.substring(0,3).equals("bab"))
    return true;
  else
    return hasBAB(str.substring(1));
}

但你真的应该使用String.contains

【讨论】:

  • 因为这必须是一个递归函数,所以这个答案是可以接受的。这显然不是一个通用的解决方案,因为它在性能方面是一团糟 - 字符串是不可变的,并且在这里创建了很多字符串实例。如果出于某种原因应在非学术环境中部署递归函数,请考虑创建一个 StringBuffer 或任何 char[]List&lt;Char&gt; 并继续努力。
  • 这大概可以简化为:return str.length() &gt;= 3 &amp;&amp; (str.substring(0, 3).equals("bab") || hasBAB(str.substring(1)); :)
  • @JoshM 目前不确定运算符优先级。 &amp;&amp; 的绑定是否高于 || ?我想是这样 - 在这种情况下,我猜你需要括号。
  • @JoshM 你是刚刚编辑了它们,还是它们一直存在?无论如何,现在看起来还可以;)
【解决方案2】:

无需递归;)您正在寻找String.contains

public static boolena hasBAB (String str) {
    if (String.length() < 3) return false;
    else return str.contains("bab");
}

【讨论】:

  • 但我想要一个递归:(
  • 他想要一个递归函数。我认为这更多是出于他的概念目的而不是实际目的。
  • 已接受。但是,请参阅我在另一个答案中对此的评论。
【解决方案3】:

递归应该被认为是两个部分。

1) 基本情况。这是很容易确定的微不足道的情况。 到目前为止,您所拥有的是基本案例的良好开端。 1) 字符串是否小于 3?然后返回假。 2)字符串是否以“bab”开头然后返回true。

2) 递归情况。 这会将问题拆分为更小的问题,如果您将它们拆分得足够多,希望您有一个基本案例。

@Logiraptro 有一个简单递归的好例子。

public static boolean hasBAB(String str) {
  if (str.length() < 3) return false;
  if (str.substring(0,3).equals("bab"))
    return true;
  else
    return hasBAB(str.substring(1));
}

这使用您的基本情况,并作为递归情况检查从索引一开始的字符串。这仅将我们的字符串减少了一个章程,但足以解决问题。

这意味着我们最终得到了字符串长度的堆栈级别。

我们可以做得更好吗?稍微,通过将问题分成两半,我们只需要 ln(n) 的堆栈级别,其中 n 是字符串的长度。对于大多数长度而言,这并不是什么大问题,但如果您正在搜索长度为一百万的字符串,它可能很重要。在第一个版本中,我们的堆栈深度约为 1,000,000!但有了这个二进制版本,我们只需要深入 14 层即可。

不过,这是有代价的,因为我们的解决方案涉及更多。

我们的基本案例 1) 如果字符串小于搜索字符串的长度,则返回 false。 2)如果字符串是搜索字符串的长度,如果相等则返回true,否则返回false。 3) 如果字符串出现在字符串的中点之上,则返回 true。

如果这些都不正确,我们将字符串分成两部分并递归检查该字符串。

这是该算法的一个示例,您可以将“bab”替换为您喜欢的任何字符串,尽管它尚未经过全面测试,我很确定它会没问题。

public static boolean hasBAB(String str) {
      String searchString = "bab";

      // Base cases
      if (str.length() < searchString.length()) 
          return false;

      if (str.length() == searchString.length())
      {
          if (str.equals(searchString))
          {
              return true;
          }
          return false;
      }

      int halfWay = str.length()/2;

      // Now check for the search string over the "break"
      for (int i = 0; i < searchString.length(); i++)
      {
          int startIndex = halfWay - 1 - i;
          int endIndex = startIndex + 3;
          if (startIndex >= 0)
          {
              String substring = str.substring(startIndex, endIndex);
              if (substring.equals(searchString))
              {
                  return true;
              }
          }
      }

     // Recursive Cases 
     //  We did find the search string over the break,so break the string into two equal(ish) pieces and check those 
     if(hasBAB(str.substring(0,halfWay -1)))
         return true;

     if(hasBAB(str.substring(halfWay, str.length())))
         return true;

     return false;
}

【讨论】:

  • 多么棒的解释……我读了每一个字,今天我真的学到了一些东西。我希望我能给你10个赞。这肯定是最好的答案!
  • 谢谢 - 很高兴你喜欢它。你应该看看二分搜索。相同的基本搜索,但我们可以每次将列表减半,因为它已排序,因此更好。与比较冒泡排序和快速排序相同。相同的基本思想。这是整洁的东西。
  • 不确定二进制搜索应该带来什么优势 - 它只适用于您实际上只需要处理一半的排序内容。这不是这种情况......与琐碎的方法相比,如果比赛在后半场,你会更快,但如果比赛在第一场,你会慢一些。所以刚换了。仍然是 O(n)。
  • @JohannesH.,是的-就比较而言,它们都是 O(N),但就堆栈计数而言,Logiraptor 的解决方案也是 O(N)。对于堆栈计数,二进制搜索是 O(ln(n))。所以尝试在大约 30,000 的字符串上运行这两个。基本方法给出了堆栈溢出。至少在我的计算机上,二进制方法没有。另外,我认为 Ris 出于教育目的想要这个答案(因为你永远不会真正递归地这样做)所以我认为更深入的答案将有助于他展示这两种解决方案。特别是如果接下来他想查看二分搜索或快速排序。
  • 明白你的意思。我不得不承认,我没有考虑堆栈计数,我通常没有任何可能填充它的递归任务。
猜你喜欢
  • 2021-06-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-04
  • 2013-05-06
  • 1970-01-01
  • 2010-12-03
  • 2011-10-17
  • 2012-01-23
相关资源
最近更新 更多