我尝试在JAVA中比较2个字符串,并检查它们是否相同,但有特殊情况: 两个字符串相同,但不超过一个字母(您可以添加/删除/更改该字母)
abc,abcd->好(删除'd')
abcd,abd->好(添加'c')
abcd,abdd->好(更改'd')
abc,abdd->错误(需要删除并更改超过1个字母)
abcd,abfde->错误(需要更改“ f”并添加删除“ e”)
我的想法是在两个字符串上同时运行,并每次比较每个字母,当我发现“问题”时,如果一个字符串比另一个字符串长,我只会使用1个字符串(比如:abcde,abde => a,a-> b,b-> c,d -> d, d -> e,e)
但是由于某些原因,我无法正确处理。在我的代码中感觉太多了。
public boolean sameString(String s1, String s2) {
if(Math.abs(s1.length()-s2.length()) > 1) {
return false;
}
else {
int i = 0;
int j = 0;
int count = 0;
while(i != s1.length() && j != s2.length()) {
if(s1.charAt(i) != s2.charAt(j)) {
count++;
if(s1.length() == s2.length()) {
i++;
j++;
}
else if(s1.length() > s2.length()) {
i++;
}else {
j++;
}
}else {
if(i < s1.length()) {
i++;
}
if(j < s2.length()) {
j++;
}
}
}
if(count > 1) {
return false;
}
return true;
}
}
有人可以帮助优化吗?我很确定有解决此问题的更好方法。
谢谢。
答案 0 :(得分:2)
您可以在以下条件中添加&& (count < 2)
:while ((i != s1.length()) && (j != s2.length()) && (count < 2)) {
。
您在循环内多次调用.length()
。您只需为每个字符串调用一次即可保存结果。
此外,如果必须返回boolean
,则可以仅返回if表达式。我的意思是:您不用if (something) return true;
,而只需return (something);
最后,如果要针对长字符串测试该方法,则可以利用toCharArray()
来避免在循环内调用.charAt()
。
尝试一下:
public static boolean sameString(final String s1, final String s2) {
final int s1Len = s1.length();
final int s2Len = s2.length();
if (Math.abs(s1Len - s2Len) > 1) {
return false;
}
// if the strings are long enough, using char[] may save up time
char[] shortest, longest;
if (s1Len <= s2Len) {
shortest = s1.toCharArray();
longest = s2.toCharArray();
} else {
shortest = s2.toCharArray();
longest = s1.toCharArray();
}
int diff = 0;
int offset = 0;
// if there are at least 2 different characters, there is no need to check more
for (int i = 0; (i < shortest.length) && (diff < 2) && ((i + offset) < longest.length); i++) {
if (shortest[i] != longest[i + offset]) {
diff++;
if (s1Len != s2Len) {
offset++;
}
if ((offset == 1) && ((i + offset) < longest.length) && (shortest[i] != longest[i + offset])) {
return false;
}
}
}
return (diff < 2);
}
// that's how I tested it
public static void main(final String[] args) {
System.out.println(sameString("abc", "abcd"));
System.out.println(sameString("bcd", "abcd"));
System.out.println(sameString("acd", "abcd"));
System.out.println(sameString("abcd", "abdd"));
System.out.println(sameString("abc", "abdd"));
System.out.println(sameString("abcd", "abfde"));
System.out.println(sameString("abcde", "acde"));
System.out.println(sameString("abcde", "acdee"));
System.out.println(sameString("abcde", "aced"));
System.out.println(sameString("a", ""));
System.out.println(sameString("", ""));
}
答案 1 :(得分:1)
您必须尝试类似的事情
public boolean sameString(String s1, String s2) {
if (Math.abs(s1.length() - s2.length()) > 1) {
return false;
} else {
int i = 0;
int j = 0;
while (i < s1.length() && j < s2.length()) {
if(Math.abs(i-j)>1) {
return false;
} else if (s1.charAt(i) != s2.charAt(j)) {
if (s1.length()>s2.charAt(j)) {
i++;
continue;
} else if (s1.length()<s2.charAt(j)){
j++;
continue;
}
return false;
}
i++;
j++;
}
if(i < s1.length() || j < s2.length()) {
return false;
}
return true;
}
}
答案 2 :(得分:1)
这是我尝试的解决方案:
public class Test {
public static void main(String[] args) {
System.out.println(compareStrings("abc", "abcd")); // true
System.out.println(compareStrings("abcd", "abd")); //
System.out.println(compareStrings("abcd", "abdd"));
System.out.println(compareStrings("abc", "abdd"));
System.out.println(compareStrings("abcd", "abfde"));
System.out.println(compareStrings("abcd", "afbd"));
System.out.println(compareStrings("a", ""));
System.out.println(compareStrings("", "a"));
System.out.println(compareStrings("abc", "abc"));
System.out.println(compareStrings("a", "a"));
}
private static boolean compareStrings(String first, String second) {
if (Math.abs(first.length() - second.length()) > 1) {
return false;
}
int mismatchCount = 0;
int i = 0;
int j = 0;
while (i < first.length() && j < second.length()) {
if (first.charAt(i) != second.charAt(j)) {
if (mismatchCount == 1) {
return false;
}
mismatchCount++;
if (first.length() > second.length()) {
i++;
} else if (first.length() < second.length()) {
j++;
} else {
i++;
j++;
}
} else {
i++;
j++;
}
}
// for extra character left
if (i < first.length() || j < second.length()) {
mismatchCount++;
}
return mismatchCount <= 1;
}
}
输出:
true
true
true
false
false
false
true
true
true
true
答案 3 :(得分:1)
我认为以下是更简单的解决方案:
公共类StrTest {
public static void eval(String a, String b) {
if (a.length() > b.length()) {
String c = b;
b = a;
a = c;
}
if (a.length() <= b.length()) {
int i=0; char[] tmp = b.toCharArray();
for (char c : a.toCharArray()) {
if (tmp[i] == c) {
tmp[i]= ' ';
}
i++;
}
b = new String(tmp).trim();
}
System.out.println(b.length() > 1 ? "KO" : "OK");
}
public static void main(String[] arg) {
String a = "cba";
String b = "abcd";
eval(a, b);
}
}
答案 4 :(得分:0)
我建议另一个简洁的答案:
public class StrTest {
public static void eval(String a, String b) {
StringBuilder s1 = new StringBuilder(a.length() > b.length() ? b : a);
StringBuilder s2 = new StringBuilder(a.length() > b.length() ? a : b);
for (int i = 0; i < s1.length(); i++) {
if (s1.charAt(i) == s2.charAt(i)) {
s2.setCharAt(i, ' ');
}
}
System.out.println(new String(s2).trim().length() > 1 ? "KO" : "OK");
}
public static void main(String[] arg) {
String a = "abc";
String b = "abcd";
eval(a, b);
}
}