我必须编写一个函数,它将两个单词(字符串)作为参数,并确定是否只使用一个一阶变换将第一个单词转换为第二个单词。
一阶转换只会改变单词中的一个字母
允许的转换是:插入,删除和替换
有什么建议吗?任何Java示例都会很棒!
答案 0 :(得分:5)
想想:如果你只允许进行一次转换,那么“之前”和“之后”之间的长度差异应该会给你一个非常强烈的暗示,即这三个转换中哪一个有成功的机会。出于同样的原因,你可以一眼就看出哪些变换根本不可能。
一旦你决定了哪个转型,问题的其余部分就会成为Brute Force Man和他的搭档Looping Lady的工作。
答案 1 :(得分:2)
这看起来像是家庭作业,所以我不打算给你答案,但是当你接近这样的问题时,最好的办法就是开始草拟一些想法。将问题分解为更小的块,然后变得更容易解决。
例如,让我们看一下插入操作。要插入一个字母,那么我们插入字母的单词的长度是怎么回事?增加还是减少呢?如果我们增加单词的长度,并且这个新单词的长度不等于我们试图匹配的单词的长度,那么它告诉你什么?因此,这里的一个条件是,如果要对第一个单词执行插入操作以使其与第二个单词匹配,则第一个单词必须具有已知长度。
您可以将类似的想法应用于其他两项操作。
因此,一旦建立了这些条件,就可以更容易地开发算法来解决问题。
在这样的任何类型的任务中,重要的是要仔细思考。不要只问别人,“给我代码”,你什么都不会这样。当你遇到困难时,可以寻求帮助(但告诉我们你到目前为止所做的事情),但是家庭作业的目的是学习。
答案 2 :(得分:1)
您可以使用Levenshtein距离并且仅允许距离为1(这意味着必须更改一个char)。有几个实现只是google“Levenshtein java”左右。
另一个“不那么聪明”,但工作的东西将是好老蛮力。只需尝试每个字符的每个情况,你就可以得到你想要的东西。 : - )
答案 3 :(得分:1)
如果您需要检查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])
);
}
[1|] = true
[123|] = false
[this|that] = false
[tit|tat] = true
[word|sword] = true
[desert|dessert] = true
[lulz|lul] = true
[same|same] = false