使用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个字符串之间的汉明距离的主要内容,如果未能解决你的问题,请参考以下文章

算法 - 计算汉明距离

什么是汉明距离,我如何为 CRC 方案确定它?

快速汉明距离评分

从 Python 开始 - 字符串列表的汉明距离

算法

汉明距离