Если вам нужно проверить, есть ли одно и ровно одно редактирование от s1
до s2
, то это очень легко проверить с помощью простого линейного сканирования.
- Если оба имеютодинаковой длины, тогда должен быть ровно один индекс, в котором эти два значения отличаются
- Они должны согласовываться с общим самым длинным префиксом, затем пропускают ровно один символ из обоих, затем они должны согласовывать общий суффикс
- Если один короче другого, тогда разница в длине должна составлять ровно один
- Они должны совпадать с общим длинным префиксом, тогда пропускается ровно один символ из более длинногоВо-первых, они должны согласовать общий суффикс
Если вы также разрешите редактирование нуля от s1
до s2
, просто проверьте, являются ли они equal
.
Вот реализация Java:
static int firstDifference(String s1, String s2, int L) {
for (int i = 0; i < L; i++) {
if (s1.charAt(i) != s2.charAt(i)) {
return i;
}
}
return L;
}
static boolean oneEdit(String s1, String s2) {
if (s1.length() > s2.length()) {
return oneEdit(s2, s1);
}
final int L = s1.length();
final int index = firstDifference(s1, s2, L);
if (s1.length() == s2.length() && index != L) {
return s1.substring(index+1).equals(s2.substring(index+1));
} else if (s2.length() == L + 1) {
return s1.substring(index).equals(s2.substring(index+1));
} else {
return false;
}
}
Затем мы можем проверить это следующим образом:
String[][] tests = {
{ "1", "" },
{ "123", "" },
{ "this", "that" },
{ "tit", "tat" },
{ "word", "sword" },
{ "desert", "dessert" },
{ "lulz", "lul" },
{ "same", "same" },
};
for (String[] test : tests) {
System.out.printf("[%s|%s] = %s%n",
test[0], test[1], oneEdit(test[0], test[1])
);
}
Это печатает (, как видно на ideone.com):
[1|] = true
[123|] = false
[this|that] = false
[tit|tat] = true
[word|sword] = true
[desert|dessert] = true
[lulz|lul] = true
[same|same] = false