我正在使用codingbat.com来进行一些java练习。其中一个字符串问题,'withoutString'如下:
给定两个字符串base和remove,返回基本字符串的一个版本,其中删除了删除字符串的所有实例(不区分大小写)。 您可以假设删除字符串的长度为1或更长。仅删除不重叠的实例,因此使用“xxx”删除“xx”会留下“x”。 可以在以下位置找到此问题:http://codingbat.com/prob/p192570
正如您从下面的Dropbox链接屏幕截图中看到的那样,除了三个以及最后一个称为“其他测试”之外,所有的运行都通过了。问题是,即使它们被标记为不正确,我的输出也会正确匹配正确答案的预期输出。
以下是我输出的屏幕截图:
这是我正在使用的代码:
public String withoutString(String base, String remove) {
String result = "";
int i = 0;
for(; i < base.length()-remove.length();){
if(!(base.substring(i,i+remove.length()).equalsIgnoreCase(remove))){
result = result + base.substring(i,i+1);
i++;
}
else{
i = i + remove.length();
}
if(result.startsWith(" ")) result = result.substring(1);
if(result.endsWith(" ") && base.substring(i,i+1).equals(" ")) result = result.substring(0,result.length()-1);
}
if(base.length()-i <= remove.length() && !(base.substring(i).equalsIgnoreCase(remove))){
result = result + base.substring(i);
}
return result;
}
答案 0 :(得分:6)
您的解决方案失败并且编码蝙蝠时存在显示错误。
正确的输出应该是:
withoutString("This is a FISH", "IS") -> "Th a FH"
你的是:
withoutString("This is a FISH", "IS") -> "Th a FH"
你的失败是因为它正在删除空格,但是,由于HTML删除了额外的空格,编码bat没有显示正确的期望和运行输出字符串。
这种递归解决方案通过了所有测试:
public String withoutString(String base, String remove) {
int remIdx = base.toLowerCase().indexOf(remove.toLowerCase());
if (remIdx == -1)
return base;
return base.substring(0, remIdx ) +
withoutString(base.substring(remIdx + remove.length()) , remove);
}
以下是最佳迭代解决方案的示例。它具有比递归解决方案更多的代码,但速度更快,因为函数调用的次数要少得多。
public String withoutString(String base, String remove) {
int remIdx = 0;
int remLen = remove.length();
remove = remove.toLowerCase();
while (true) {
remIdx = base.toLowerCase().indexOf(remove);
if (remIdx == -1)
break;
base = base.substring(0, remIdx) + base.substring(remIdx + remLen);
}
return base;
}
答案 1 :(得分:3)
我刚刚在IDE中运行了您的代码。 它正确编译并匹配codingbat 上显示的所有测试。编码包的测试用例肯定存在一些错误。
如果您感到好奇,可以通过一行代码解决此问题:
public String withoutString(String base, String remove) {
return base.replaceAll("(?i)" + remove, ""); //String#replaceAll(String, String) with case insensitive regex.
}
正则表达式解释:
String#replaceAll(String,String)采用的第一个参数就是所谓的Regular Expression或“ regex ”。
Regex是一个在字符串中执行模式匹配的强大工具。在这种情况下,正在使用的正则表达式是(假设remove
等于IS
):
(?i)IS
此特定表达式包含两部分:(?i)
和IS
。
IS
完全匹配字符串"IS"
,仅此而已。
(?i)
只是告诉正则表达式引擎忽略大小写的标志。
使用(?i)IS
,所有:IS
,Is
,iS
和is
都将匹配。
作为补充,这几乎等同于正则表达式:(IS|Is|iS|is)
,(I|i)(S|s)
和[Ii][Ss]
。
修改强>
原来你输出不正确并且按预期失败。请参阅:dansalmo's answer。
答案 2 :(得分:1)
请在下面找到我的解决方案
public String withoutString(String base, String remove) {
final int rLen=remove.length();
final int bLen=base.length();
String op="";
for(int i = 0; i < bLen;)
{
if(!(i + rLen > bLen) && base.substring(i, i + rLen).equalsIgnoreCase(remove))
{
i +=rLen;
continue;
}
op += base.substring(i, i + 1);
i++;
}
return op;
}
有些东西在编码时变得非常奇怪,但这只是其中之一。
答案 3 :(得分:1)
我正在添加到以前的解决方案,但使用StringBuilder进行更好的练习。最值得赞扬的是Anirudh。
public String withoutString(String base, String remove) {
//create a constant integer the size of remove.length();
final int rLen=remove.length();
//create a constant integer the size of base.length();
final int bLen=base.length();
//Create an empty string;
StringBuilder op = new StringBuilder();
//Create the for loop.
for(int i = 0; i < bLen;)
{
//if the remove string lenght we are looking for is not less than the base length
// and the base substring equals the remove string.
if(!(i + rLen > bLen) && base.substring(i, i + rLen).equalsIgnoreCase(remove))
{
//Increment by the remove length, and skip adding it to the string.
i +=rLen;
continue;
}
//else, we add the character at i to the string builder.
op.append(base.charAt(i));
//and increment by one.
i++;
}
//We return the string.
return op.toString();
}
答案 4 :(得分:0)
@Daemon
您的代码有效。感谢正则表达式的解释。虽然dansalmo指出codingbat错误地显示了预期的输出,但是我通过代码的一些额外行来不必考虑以下双重空格:
public String withoutString(String base, String remove){
String result = base.replaceAll("(?i)" + remove, "");
for(int i = 0; i < result.length()-1;){
if(result.substring(i,i+2).equals(" ")){
result = result.replace(result.substring(i,i+2), " ");
}
else i++;
}
if(result.startsWith(" ")) result = result.substring(1);
return result;
}
答案 5 :(得分:0)
public String withoutString(String base, String remove) {
String temp = base.replaceAll(remove, "");
String temp2 = temp.replaceAll(remove.toLowerCase(), "");
return temp2.replaceAll(remove.toUpperCase(), "");
}
答案 6 :(得分:0)
public String withoutString(String base, String remove){
return base.replace(remove,"");
}
答案 7 :(得分:0)
Taylor的解决方案是最有效的解决方案,但是我还有另一种解决方案,它是一个幼稚的解决方案,并且可以工作。
public String withoutString(String base, String remove) {
String returnString = base;
while(returnString.toLowerCase().indexOf(remove.toLowerCase())!=-1){
int start = returnString.toLowerCase().indexOf(remove.toLowerCase());
int end = remove.length();
returnString = returnString.substring(0, start) + returnString.substring(start+end);
}
return returnString;
}