使用Core Java中的递归机制在另一个字符串中查找字符串

时间:2010-12-25 13:56:31

标签: java recursion

我有以下问题陈述

PS:给定一个字符串“str”和一个非空子字符串“sub”,如果“sub”中至少有“N”个副本出现在“string somewhere”中,则计算“递归”,可能带有“重叠”。 N将是非负数。

Example are as shown below
strCopies("catcowcat", "cat", 2) → true
strCopies("catcowcat", "cow", 2) → false
strCopies("catcowcat", "cow", 1) → true
strCopies("iiijjj", "ii", 2) → true

我编写了如下所示的代码(没有递归),并且对于少数测试用例工作正常,除了标记为FAIL的其他测试用例。

:::代码如下所示:::

public boolean strCopies(String str, String sub, int n) {    
    int len = sub.length();    
    int result=0;    
    if(len>0){    
       int start = str.indexOf(sub);    
       while(start !=-1){    
              result++;    
              start = str.indexOf(sub,start+len);                     
       }
    }          
   if(result==n){
        return true;
   }else return false; 
}

运行以上代码,如下所示(标记为BOLD是FAILED TEST CASES)

Expected This Run
strCopies("catcowcat", "cat", 2) → true true OK
strCopies("catcowcat", "cow", 2) → false false OK
strCopies("catcowcat", "cow", 1) → true true OK
strCopies("iiijjj", "ii", 2) → true false FAIL
strCopies("iiiiij", "iii", 3) → true false FAIL
strCopies("ijiiiiij", "iiii", 2) → true false FAIL

你能检查并告诉我FAIL TEST CASES的代码有什么问题吗?我无法考虑重叠的情况。

5 个答案:

答案 0 :(得分:3)

好吧,你的第一个问题是你的方法不是递归的。我怀疑您希望使用substring以及indexOf ...

至于为什么你当前的方法不起作用,我怀疑是因为你使用start + len代替start + 1来找到下一个起始位置。因此,当试图在“iii”中找到“ii”时,你应该先看看位置0,然后是位置1 - 目前你正在查看位置2,这意味着它不会从1开始找到第二个“ii”

答案 1 :(得分:2)

首先,您的解决方案不是递归的(strCopies不会自行调用)。

以下是对算法的递归版本的建议:

public static boolean strCopies(String str, String sub, int n) {
    if (str.isEmpty())
        return n == 0;
    int remainingN = str.startsWith(sub) ? n - 1 : n;
    return strCopies(str.substring(1), sub, remainingN);
}

(All your test-cases pass.)


顺便说一句,请注意你最后一行代码:

if(result==n)
    return true;
else
    return false; 

总是可以简单地替换

return result == n;

答案 2 :(得分:1)

public class StackOverflow {

 public static void main(String[] args) {
  String string = "catcowcat";
  String substring = "cat";
  System.out.println(string + " has " + findNumberOfStrings(string, substring, 0) + " " + substring);
 }

 private static int findNumberOfStrings(String string, String substring, int count){
  if (string.length() == 0){
   return count + 0;
  }
  if (string.length() < substring.length()){
   return count + 0;
  }
  if (string.contains(substring)){
   count++;
   string = string.replaceFirst(substring, "");
   return findNumberOfStrings(string, substring, count);
  }
  return count;
 }

}

答案 3 :(得分:0)

问题的纯递归代码是:

public boolean strCopies(String str, String sub, int n) {
   if(n==0) return true;
   if(str.length()==0) return false;
   if(str.length()<sub.length()) return false;
   if(str.startsWith(sub)) return strCount(str.substring(1),sub, n, 1);
   return strCopies(str.substring(1),sub,n);
}

public boolean strCount(String str , String sub , int n , int count ) {
   if( count>= n) return true;
   if(str.length()==0) return false;
   if(str.length()<sub.length()) return false;
   if(str.startsWith(sub)) {
   count++;
   if( count>= n) return true;
   }
   return strCount(str.substring(1),sub, n , count );
}

我们必须在str字符串中维护sub的出现次数。但是在strCopies函数的递归调用中如果我们取计数变量,每次调用函数的值都会重新初始化(我们不能在函数的内存中维护计数而不能继续添加到它之前的值)。因此,为了保持count的值,我们将count的值传递给另一个函数strCount(作为return strCount(str.substring(1), sub, n, count ) ),它也可以递归地工作并且可以执行count ++,因为它只使用count值调用而count不会被重新赋值而不是get继续前进。

答案 4 :(得分:0)

基本的想法是你搜索子词的索引,然后你发送新的字符串,这个字符串在你找到单词的索引之后开始一个字符,因为你允许重叠。

public boolean strCopies(String str, String sub, int n) {

 if (str == null || str.equals("") || str.length() < sub.length())
  if (n == 0)
    return true;
  else 
    return false;


 int index =  str.indexOf(sub);
 if (index != -1)
  return false || strCopies(str.substring(index + 1),sub,--n);
 else
  return false || strCopies("",sub,n);

}