使用 XOR return true 比较两个字符串,但字符串不同

Comparing two string using XOR return true but the strings are different

我正在测试一些识别字谜的方法,我发现了一个让我措手不及的情况。我发现可以使用 XOR,所以我使用 XOR 运算符对其进行了测试。这是我的代码:

public static void main(String[] args) {
    // TODO code application logic here
    
    String s1 = "pe";
    String s2 = "ep";
    
    System.out.println(isAnagram(s1, s2));
}

private static boolean isAnagram(String firstString, String secondString) 
{
    int control = 0;
    
    System.out.println("Comparing: " + firstString + " and " + secondString);
    
    for (int i = 0; i < firstString.length(); i++) {
        control = control ^ firstString.charAt(i);
    }
    
    for (int i = 0; i < secondString.length(); i++) {
        control = control ^ secondString.charAt(i);
    }
    
    System.out.println("Control: " + control);
    return (control == 0);
}

当 2 个字符串具有相同的字符集时,即使它们的顺序不同,control 变量也是 0 returning true to anagram。但是,当 2 个字符串不同时,control 的值 > 0 returning false to anagram。 我尝试使用很多词,其中大部分都有效,但出于某种原因,它经常出现一些奇怪的情况,例如,“v”和“ils”return 对字谜或“tat”和“atata”正确return也是真的。

我想了解为什么会发生这种情况,我应该怎么做才能不再出现这种情况。

很简单,您使用的算法无法正常工作。由于 XOR 是关联的和可交换的(例如,加法),因此无论执行 XOR 的顺序如何,将字符串中的所有字符异或在一起会产生相同的值。同样,无论您以何种顺序进行加法运算,您都将获得相同的数组值总和。

但是,与加法一样,XOR 也会丢弃信息。您不能从结果返回到原始值:1+3 = 2+2 = 0+4。与 XOR 类似:1^3 = 6^4 = 0^2.

XOR 的一个特殊功能是 a ^ a = 0 对于任何 a;还有a ^ 0 = a。 (这些语句是相关的。)所以你总是可以只删除成对的相同字符; atata 的 XOR 组合与 tat 的组合相同,也与 a.

相同

因此,由于按位运算符的功能,您将继续 运行 解决这些问题。 v 的 acsii 为 01110110,i 的 acsii 为 01101001,l 的 acsii 为 01101100,s 的 acsii 为 01110011.

这是导致返回 00000000 的逐行比较。

v - 01110110
i - 01101001
new:00011111
l - 01101100
new:01110011
s - 01110011
new:00000000

每个“新”都是您的控制和导致 00000000 或您的真实结果的个别比较。