Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 计算以相同子字符串开始和结束的最大子字符串的长度_Java_Algorithm_String_Recursion - Fatal编程技术网

Java 计算以相同子字符串开始和结束的最大子字符串的长度

Java 计算以相同子字符串开始和结束的最大子字符串的长度,java,algorithm,string,recursion,Java,Algorithm,String,Recursion,以下是问题陈述: PS:给定一个字符串和一个非空子字符串sub,递归计算以sub开头和结尾的最大子字符串,并返回其长度。 示例: strDist(“猫头鹰”、“猫”)→ 9 strDist(“猫头鹰”、“奶牛”)→ 3 strDist(“cccatcowcatxx”、“cat”)→ 9 下面是我的代码: (没有递归)//因为我发现用递归很难实现 public int strDist(String str, String sub){ int idx = 0;

以下是问题陈述:

PS:给定一个字符串和一个非空子字符串sub,递归计算以sub开头和结尾的最大子字符串,并返回其长度。

示例:

strDist(“猫头鹰”、“猫”)→ 9

strDist(“猫头鹰”、“奶牛”)→ 3

strDist(“cccatcowcatxx”、“cat”)→ 9

下面是我的代码: (没有递归)//因为我发现用递归很难实现

    public int strDist(String str, String sub){    
        int idx = 0;     
        int max;    
        if (str.isEmpty()) max = 0;    
        else max=1;                        
        while ((idx = str.indexOf(sub, idx)) != -1){     
            int previous=str.indexOf(sub, idx);     
            max = Math.max(max,previous);     
            idx++;                           
        }     
     return max;    
   }
如下图所示,它对少数人有效,但对其他人无效。

应进行此运行

strDist(“猫头鹰”、“猫”)→ 9.6失败

strDist(“猫头鹰”、“奶牛”)→ 3 3正常

strDist(“cccatcowcatxx”、“cat”)→ 9 8失败

strDist(“abccatwcatcatxyz”、“cat”)→ 12正常

标准列表(“xyx”、“x”)→ 3 2失败
标准列表(“xyx”、“y”)→ 1 1正常
标准列表(“xyx”、“z”)→ 0 1失败
标准(“z”、“z”)→ 1 1正常
标准(“x”、“z”)→ 0 1失败
strDist(“,“z”)→ 0 0正常

strDist(“hihellohihi”,“hi”)→ 13 11失败

strDist(“hihellohihi”,“hih”)→ 5 9失败

strDist(“hihellohihi”、“o”)→ 16失败

strDist(“hihellohihi”、“ll”)→ 2 4失败


您能告诉我代码有什么问题,以及如何返回以sub开头和结尾的最大子字符串及其各自的长度。有一个简单的解决方案,效率更高。找到子字符串的第一个和最后一个匹配项,您就有了答案。无需搜索所有事件

public int strDist(String str, String sub) {
  int first = str.indexOf(sub);
  if (first == -1)
    return 0;
  int last = str.lastIndexOf(sub);
  return last - first + sub.length();
}

代码的问题是返回子字符串最后一次出现的索引。您似乎也在尝试查找最后一次出现的第二行,最后一行至少应该是
max-previous
,但是您还需要添加子字符串的长度,使其成为
max-previous+sub.length()
。您还需要将
previous
的声明移到while循环之外。但是,您可以找到第二次和最后一次出现之间的距离,如果没有正好两次出现(例如
“foocabar”
“catfoocabercat”
),则该距离将失败

递归地解决这个问题有点过分,首先也是最重要的,因为您不能使用内置的
String.indexOf()
函数。但由于这是家庭作业,这里有一个快速尝试:

public static int indexOf(String str, String sub, int start, int direction) {
  if (start < 0 || start > str.length() - sub.length())
    return -1;
  if (str.substring(start, start + sub.length()).equals(sub))
    return start;
  return indexOf(str, sub, start+direction, direction);
}

public static int strDistRecursive(String str, String sub) {
  int first = indexOf(str, sub, 0, 1);
  if (first == -1)
    return 0;
  int last = indexOf(str, sub, str.length() - sub.length(), -1);
  return last - first + sub.length();
}
公共静态int indexOf(字符串str、字符串sub、int start、int direction){
如果(开始<0 | |开始>str.length()-sub.length())
返回-1;
如果(str.substring(start,start+sub.length()).equals(sub))
返回启动;
返回索引of(str、sub、start+direction、direction);
}
公共静态int-strDistRecursive(字符串str,字符串sub){
int first=indexOf(str,sub,0,1);
如果(第一个==-1)
返回0;
int last=indexOf(str,sub,str.length()-sub.length(),-1);
返回最后一个-第一个+子长度();
}

这个问题的简单解决方案是计算主字符串中子字符串的第一个索引和最后一个索引。但是如果您确实需要使用递归,下面是代码

public int strDist(String str, String sub) {
   int n = str.length();
   if(n==0) return 0; 
   if (str.startsWith(sub)) return strBack(str,sub);
   return strDist(str.substring(1) , sub);
 }

public int strBack(String str, String sub) { 
int n = str.length();
if (n ==0) return 0;
if(str.endsWith(sub)) return n ;
 return strBack(str.substring(0,n-1),sub);
  }

整个方法是,strDist函数从开头开始寻找子字符串,strBack从结尾开始寻找子字符串,如果没有找到,str将被一个字符剥离。因此,一旦在strDist的开始处找到sub,就调用strBack,从末尾查看sub,如果找到,那么剥离的str就是我们需要的最长字符串。返回其长度

我在这里发布了我的递归解决方案。其背后的逻辑是从左到右切分,直到在开始处找到sub,然后从右切分,直到在结束处找到sub

public int strDist(String str, String sub) 
{
    if (0 == str.length())
    {
        return 0;
    }
    else if (!str.startsWith(sub))
    {
        //chop from left
        return strDist(str.substring(1), sub);    
    }
    else if (!str.endsWith(sub))
    {
        //chop from right
        return strDist(str.substring(0, str.length() - 1), sub);
    }
    else if (str.startsWith(sub) && str.endsWith(sub))
    {
        //got a substring subXXXsub
        return str.length();
    }
    return 0;
}

有一个很好的简短递归解决方案。 对于其他提出的解决方案来说,这不是什么创新,但它更简短、更清晰,因此更容易理解:

public int strDist(String str, String sub) {
  if (str.length()==0) return 0;
  if (!str.startsWith(sub))
      return strDist(str.substring(1),sub);
  if (!str.endsWith(sub))
    return strDist(str.substring(0,str.length()-1),sub);
  return str.length();
}

这是我的解决方案版本。它应该能正常工作-但是,在这个站点(CODINGBAT),我不能通过检查


公共int strist(字符串str,字符串sub)
{

如果(str.length()@marcog,你能告诉我怎么做吗。困惑:-(它不工作。strdit(“猫头鹰”,“猫”)→ 9.3失败,如果只发生一次,您的解决方案就会起作用。并非所有情况都是这样Hanks@finnw,当您修复它时,我只是在修复它。:)还有一个丢失的
,是我修复的。哦,天哪,这太容易了,我没有及时完成。我用while循环和indexOf打破了我的脑袋,然后就把它关上了,谢谢大家。有什么办法吗recursively@Deepak你已经关闭了这个。递归方法不是你在这里要求的。。。
public int strDist(String str, String sub) {
  if (str.length()==0) return 0;
  if (!str.startsWith(sub))
      return strDist(str.substring(1),sub);
  if (!str.endsWith(sub))
    return strDist(str.substring(0,str.length()-1),sub);
  return str.length();
}