问题描述
我正在做这个一毛钱的递归问题,我们必须返回第一个索引,其中子字符串出现在更大的字符串中。如果未找到,则返回 -1。不鼓励使用辅助函数。
indexOf("Hello","Lo") --> 3
,因为“lo”首先出现在索引 3 处。
indexOf("Hello","H") --> 0
,因为“H”首先出现在索引 0 处。
indexOf("Hello","x") --> -1
,因为“x”根本没有出现。
好消息是:我已经想通了!
public static int indexOf(String s1,String s2) {
//Invalid cases: empty string or invalid input,where s1 length is less than the substring length.
//Base case: If s1,sliced to the same length as s2,equals s2,then return 0.
//Otherwise,return recursively + 1.
if (s1.length() == 0 | s1.length() < s2.length()) {
return -1;
} else if (s1.substring(0,s2.length()).equals(s2)) {
return 0;
}
return indexOf(s1.substring(1,s1.length()),s2) + 1;
}
那么如果它有效,问题是什么?问题是整个返回 -1 的事情。它返回正确的子字符串索引,但无效输入不返回 -1。这个递归函数建立在这个想法之上,当它进一步向下遍历子字符串时,它将与它一起进行索引,所以如果在“hello”中找不到,它会转到“ello”并在下面塞入一个 1 索引它的帽子,因为我们现在知道索引(如果存在)至少 1。
问题是,随着堆栈帧的深入,它们不断地递增 1,因此 -1 没有效果。如果我将 s2 设置为类似于“x”的内容,它只会返回“4”,即它遍历“hello”子字符串的次数。没有一个数字来跟踪堆栈帧,我不能通过说“返回 -5”或其他什么来使它等于 -1。有没有办法让它遍历整个字符串,不断增加 1,但在最后以某种方式,如果找不到 s2 则返回 -1?
硬编码版本(我最喜欢的递归策略):
public static int indexOf(String s1,String s2) {
if (s1.length() == 0 | s1.length() < s2.length()) {
return -1;
} else if (s1.substring(0,s2.length()).equals(s2)) {
return 0;
} else if (s1.substring(1,1 + s2.length()).equals(s2)) {
return 0 + 1;
} else if (s1.substring(2,2 + s2.length()).equals(s2)) {
return 0 + 1 + 1;
} else if (s1.substring(3,3 + s2.length()).equals(s2)) {
return 0 + 1 + 1 + 1;
} else if (s1.substring(4,4 + s2.length()).equals(s2)) {
return 0 + 1 + 1 + 1 + 1; //what the other function returned + 1
}
return -1;
}
它以这种硬编码的方式工作得非常完美。我意识到问题在于最后一个“返回 -1”,它实际上必须在开始而不是结束时才能工作。我只显示这个以防万一。
解决方法
存储递归调用的结果,如果是 -1
,则返回 -1
。
int result = indexOf(s1.substring(1,s1.length()),s2);
return result != -1 ? result + 1 : -1;