使用for循环获取2个字符串之间的汉明距离
Posted
技术标签:
【中文标题】使用for循环获取2个字符串之间的汉明距离【英文标题】:Using for loop to get the Hamming distance between 2 strings 【发布时间】:2013-04-22 01:30:43 【问题描述】:在此任务中,我需要获取两个字符串序列 1 和序列 2 之间的汉明距离(两个相等长度的字符串之间的汉明距离是对应符号不同的位置数 - 来自***)。
首先我制作了 2 个新字符串,这是 2 个原始字符串,但都使用小写字母,以便于比较。然后我求助于使用 for 循环和 if 来比较两个字符串。对于这 2 对字符串中字符的任何差异,循环会将 1 添加到 int x = 0。方法的返回将是此 x 的值。
public static int getHammingDistance(String sequence1, String sequence2)
int a = 0;
String sequenceX = sequence1.toLowerCase();
String sequenceY = sequence2.toLowerCase();
for (int x = 0; x < sequenceX.length(); x++)
for (int y = 0; y < sequenceY.length(); y++)
if (sequenceX.charAt(x) == sequenceY.charAt(y))
a += 0;
else if (sequenceX.charAt(x) != sequenceY.charAt(y))
a += 1;
return a;
那么代码看起来足够好并且功能足够吗?我可以修复或优化代码吗?提前致谢。我是个大菜鸟,如果我问了什么愚蠢的问题,请原谅我
【问题讨论】:
anything I could do to fix
是属于这里的问题。 optimize
问题属于代码审查
这个问题更适合codereview.stackexchange.com。你也会在那里得到更好的答案。
您的代码也没有输出正确的答案。我用 abcd 和 abdd 测试,输出是 12
你看过莱文斯坦距离吗?有很多库可以做到这一点,包括 apache commons
@isti_spl 请注意,作业标签已被解除:meta.stackexchange.com/questions/147100/…
【参考方案1】:
从我的观点来看,以下实现是可以的:
public static int getHammingDistance(String sequence1, String sequence2)
char[] s1 = sequence1.toCharArray();
char[] s2 = sequence2.toCharArray();
int shorter = Math.min(s1.length, s2.length);
int longest = Math.max(s1.length, s2.length);
int result = 0;
for (int i=0; i<shorter; i++)
if (s1[i] != s2[i]) result++;
result += longest - shorter;
return result;
-
使用数组,避免为每个需要比较的单个字符调用两个方法(charAt);
避免当一个字符串比另一个字符串长时出现异常。
【讨论】:
【参考方案2】:您的代码完全关闭。 正如你自己所说,距离是字符串不同的地方的数量 - 所以你应该只有 1 个循环,一次遍历两个字符串。相反,您有 2 个嵌套循环,它们将字符串 a 中的每个索引与字符串 b 中的每个索引进行比较。
另外,编写导致a+=0
的 if 条件是浪费时间。
试试这个:
for (int x = 0; x < sequenceX.length(); x++) //both are of the same length
if (sequenceX.charAt(x) != sequenceY.charAt(x))
a += 1;
此外,这仍然是一种幼稚的方法,可能不适用于复杂的 unicode 字符(其中 2 个字符在逻辑上可以相等但字符代码不同)
【讨论】:
感谢您的帮助。在问题的范围内,它会很好地完成工作。再次感谢:D【参考方案3】:public static int getHammingDistance(String sequenceX, String sequenceY)
int a = 0;
// String sequenceX = sequence1.toLowerCase();
//String sequenceY = sequence2.toLowerCase();
if (sequenceX.length() != sequenceY.length())
return -1; //input strings should be of equal length
for (int i = 0; i < sequenceX.length(); i++)
if (sequenceX.charAt(i) != sequenceY.charAt(i))
a++;
return a;
【讨论】:
【参考方案4】:您的代码没问题,但我建议您进行以下改进。
-
不要使用
charAt()
的字符串。在循环之前使用toCharArray()
从字符串中获取字符数组,然后使用该数组。这更具可读性和更有效。
结构
if (sequenceX.charAt(x) == sequenceY.charAt(y))
a += 0;
else if (sequenceX.charAt(x) != sequenceY.charAt(y))
a += 1;
看起来多余。将其修复为: if (sequenceX.charAt(x) == sequenceY.charAt(y)) 一个+= 0; 别的 一个 += 1;
此外,考虑到我建议您使用数组,请将其更改为:
a += seqx[x] == seqY[x] ? 0 : 1
更少的代码更少的错误......
编辑:正如@radai 所述,您根本不需要if/else
结构:将0
添加到a
是多余的。
【讨论】:
"不要使用字符串的charAt()。在循环之前使用toCharArray()从字符串中获取char数组,然后使用这个数组。这样更具可读性和更有效" --> 真的吗什么时候有即时编译?我的意思是我自己没有测试过,但我想 charAt 会被优化掉。以上是关于使用for循环获取2个字符串之间的汉明距离的主要内容,如果未能解决你的问题,请参考以下文章