任务是:给定一个字符串和一个非空子字符串sub,递归计算以sub开头和结尾的最大子字符串,并返回其长度。
示例:
strDist("catcowcat", "cat") → 9
strDist("catcowcat", "cow") → 3
strDist("cccatcowcatxx", "cat") → 9
你能看看我的代码,告诉我它有什么问题吗?
public int strDist(String str, String sub)
{
if(str.length()<sub.length())
return 0;
if(str.length()==sub.length()&&str.equals(sub))
return str.length();
if(str.length()<2)
{
if(str.contains(sub))
{
return 1;
}
return 0;
}
if (str.length()==2)
{
if (sub.length()==2 && str.equals(sub))
return 2;
if (str.contains(sub))
return 1;
return 0;
}
if(str.length()>2)
{
if(str.startsWith(sub)&&str.endsWith(sub))
{
return str.length();
}
if(str.substring(0,sub.length()).equals(sub))
{
strDist(str.substring(0,str.length()-2),sub);
}
if(str.substring(str.length()-sub.length(),str.length()-1).equals(sub))
strDist(str.substring(1,str.length()-1),sub);
}
return strDist(str.substring(1,str.length()-1),sub);
}
它不适用于大小写 strDist(“嗨嗨嗨”、“嗨”)
→ 5 并返回零。
您的实现很难理解。描述算法比提供实现更合适。
基于描述,下面是我的实现,我觉得简洁易懂。
class Example {
private static int indexOf(String str, int idx, String sub, int res) {
if (str.length() < sub.length()) return res;
int tmp = str.indexOf(sub, idx);
if (tmp < 0) return res;
return Math.max(tmp, indexOf(str, tmp + 1, sub, res));
}
public static int strDist(String str, String sub) {
if (str.length() < sub.length()) return 0;
int from = str.indexOf(sub);
int to = indexOf(str, from + 1, sub, from);
return to - from + sub.length();
}
public static void main(String[] args) {
System.out.println();
System.out.println(strDist("catcowcat", "cat"));
System.out.println(strDist("catcowcat", "cow"));
System.out.println(strDist("cccatcowcatxx", "cat"));
System.out.println(strDist("hiHellohihihi", "hih"));
}
}
结果:
9
3
9
5
这是我解决它的方法,有点相似,但我发现它更简单(希望有帮助):
public int strDist(String str, String sub) {
if(str.length() < sub.length())
return 0;
if(!str.contains(sub))return 0;
if(str.startsWith(sub)&& str.endsWith(sub))
return str.length();
if(str.startsWith(sub) )
return strDist(str.substring(0,str.length()-1),sub);
if(str.endsWith(sub))
return strDist(str.substring(1,str.length()),sub);
else return strDist(str.substring(1,str.length()-1),sub);
}
首先,为了回答您的问题,我在您的代码中发现了一些问题。下面是我的更正版本,并对我所做的更改进行了评论。
public int strDist(String str, String sub) {
if (str.length() < sub.length())
return 0;
// simplified condition
if (str.equals(sub))
return str.length();
if (str.length() < 2) {
if (str.contains(sub)) {
// corrected (if str and sub are both empty strings, you don’t want to return 1)
return str.length();
}
return 0;
}
// deleted str.length() == 2 case that didn’t work correctly
if (str.startsWith(sub) && str.endsWith(sub)) {
return str.length();
}
if (str.startsWith(sub)) { // simplified
// subtracting only 1 and added return statement
return strDist(str.substring(0, str.length() - 1), sub);
}
// changed completely -- didn’t understand; added return statement, I believe this solved your test case
if (str.endsWith(sub))
return strDist(str.substring(1), sub);
return strDist(str.substring(1, str.length() - 1), sub);
}
现在如果我这样做:
System.out.println(strDist("catcowcat", "cat"));
System.out.println(strDist("catcowcat", "cow"));
System.out.println(strDist("cccatcowcatxx", "cat"));
System.out.println(strDist("hiHellohihihi", "hih"));
我得到:
9
3
9
5
第二,正如我在评论中所说的,我看不出在这里使用递归有什么意义(也许除了这个练习)。你的方法的以下版本没有,它简单得多,并且工作原理相同:
public int strDist(String str, String sub) {
int firstOccurrence = str.indexOf(sub);
if (firstOccurrence == -1) { // sub not in str
return 0;
}
int lastOccurrence = str.lastIndexOf(sub);
return lastOccurrence - firstOccurrence + sub.length();
}
最后,这可能有帮助,也可能没有帮助,递归版本不需要像您的版本那样复杂:
public int strDist(String str, String sub) {
if (sub.isEmpty()) {
throw new IllegalArgumentException("sub mustn’t be empty");
}
if (str.length() <= sub.length()) {
if (str.equals(sub)) {
return str.length();
} else { // sub cannot be in str
return 0;
}
}
if (str.startsWith(sub)) {
if (str.endsWith(sub)) {
return str.length();
} else {
return strDist(str.substring(0, str.length() - 1), sub);
}
} else {
return strDist(str.substring(1), sub);
}
}
如果可以的话,先让一些东西工作也没关系,即使它不是最简单和优雅的解决方案。当它工作或不工作时,是想办法简化的好时机。这将更容易确定错误,也便于以后的维护。特殊情况,如长度1和长度2,通常是简化的好选择:看看通用代码是否已经满足它们的要求,或者是否可以轻松实现。
给定一个字符串和一个非空子字符串,递归计算以该子字符串开始和结束的最大子字符串,并返回其长度。 我所做的没有返回正确的长度。但是因为我保存了所有可能的子字符串,所以我可以确定长度。时间复杂度应该是线性的:O(n)。 这是我尝试过的:
以下是我尝试过的,但在某些情况下失败了,但我觉得我几乎走上了正确的轨道。
我正在检查列表是否已排序,如果已排序,则返回false,如果未排序,则从开头或结尾删除列表中的maxNumer,不是在中间,而是在结尾或开头no例如[1,2,3,4] expected false [9,1,2,3,4,6,22] // expected [1,2,3,4,6]谢谢。
我试图解决Leetcode上最长的回文子串。我知道这个问题的解决方案,比如围绕中心展开或动态编程自下而上的方法。出于纯粹的教育目的,我想以自上而下的递归方式解决这个问题。我试图找到类似于这里或这里描述的解决方案。(问题略有不同)。我有这个功能: 它接受搜索的字符串开始和结束位置。返回的元组是最长palindrom的开始和结束。我试图分成以下情况: 如果s[i]==s[j],则调查最长(s,i 1,
我在记事本中加载了一个非常大的源代码文件,我试图使用它的regex搜索功能来查找所有使用属性的地方。 我需要找到设置属性<code>DESCR</code>的所有位置。我尝试只搜索没有正则表达式,但有太多的结果需要我筛选。我知道我正在寻找的代码要么以或
问题内容: 我试图得到这两种递归策略之间的区别。 我被告知的定义如下: 尾递归: 如果调用返回后无需执行任何操作,则调用为尾递归,即当调用返回时,立即从调用函数返回返回的值 Head递归: 当函数的第一条语句是递归调用时,调用是head递归的。 问题答案: 在中,递归调用在发生时先于函数中的其他处理(考虑它发生在函数的顶部或头部)。 在中,情况恰恰相反—处理发生在递归调用之前。在这两种递归样式之间