比较两个十六进制字符串以查找匹配位数

时间:2014-10-09 19:55:26

标签: java c++ hash hex bits

我有两个十六进制字符串:

string x = "928fe46f228555621c7f42f3664530f9";
string y = "56cd8c4852cf24b1182300df2448743a";

我试图将它们转换为二进制,以查找两个十六进制字符串之间的匹配位数。

我使用此函数将HEX转换为二进制:

 string GetBinaryStringFromHexString (string sHex)
 {
     string sReturn = "";
     for (int i = 0; i < sHex.length (); ++i)
     {
         switch (sHex [i])
         {
             case '0': sReturn.append ("0000"); break;
             case '1': sReturn.append ("0001"); break;
             case '2': sReturn.append ("0010"); break;
             case '3': sReturn.append ("0011"); break;
             case '4': sReturn.append ("0100"); break;
             case '5': sReturn.append ("0101"); break;
             case '6': sReturn.append ("0110"); break;
             case '7': sReturn.append ("0111"); break;
             case '8': sReturn.append ("1000"); break;
             case '9': sReturn.append ("1001"); break;
             case 'a': sReturn.append ("1010"); break;
             case 'b': sReturn.append ("1011"); break;
             case 'c': sReturn.append ("1100"); break;
             case 'd': sReturn.append ("1101"); break;
             case 'e': sReturn.append ("1110"); break;
             case 'f': sReturn.append ("1111"); break;
         }
     }
     return sReturn;
 }

所以二进制中的字符串x是 - &gt; 10010010100011111110010001101111001000101000010101010101011000100001110001111111010000101111001101100110010001010011000011111001

和二进制中的字符串y是 - &gt; 01010110110011011000110001001000010100101100111100100100101100010001100000100011000000001101111100100100010010000111010000111010

但是现在我被卡住了,我怎样才能找到两个字符串以找到匹配位的数量?我怎么算他们?

使用Java或C ++无关紧要,任何人都可以帮助

谢谢,

3 个答案:

答案 0 :(得分:4)

在Java中,这很容易。

public static int numberOfMatchingOnes(String a, String b) {
    BigInteger aNumber = new BigInteger(a, 16);
    BigInteger bNumber = new BigInteger(b, 16);

    return aNumber.xor(bNumber).bitCount();
}

在C ++中,您可以使用bitset。您正在寻找的是Hamming weight

如果你真的想在没有BigInteger 的情况下做到这一点: 取两个字符串的4个字符,将它们转换为int,xor,并计算一位。重复直到字符串结束。

public static int numberOfMatchingOnes(String a, String b) {
    if (a.length() != b.length() || a.length() % 4 != 0) {
        throw new IllegalArgumentException("invalid strings");
    }

    int totalCount = 0;
    for (int i = (a.length()-1)/4; i >= 0; i--) {
        int aValue = Integer.valueOf(a.substring(i * 4, i * 4 + 4), 16);
        int bValue = Integer.valueOf(b.substring(i * 4, i * 4 + 4), 16);
        totalCount += Integer.bitCount(aValue ^ bValue);
    }
    return  totalCount;
}

您可以查看Java Sourcecode,了解bitCount()的工作原理。

答案 1 :(得分:1)

你有两个字符串。为什么不逐个字符地浏览它们并查看它们是否匹配?将计数器初始化为零并开始为每个匹配递增它们并在循环结束时显示。更简单。

这是一个单行解决方案(具有世界上所有库的强大功能):

System.out.println(StringUtils.countMatches(new BigInteger("928fe46f228555621c7f42f3664530f9",16).xor(new BigInteger("56cd8c4852cf24b1182300df2448743a",16)).toString(2),"1"));

答案 2 :(得分:0)

这取决于您的目的,如果您想要找到它们匹配在一起的位置,您可以使用 AND 在C:

#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 & b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
} 

上面的代码从右到左比较二进制数字和两位数为1的地方然后返回1,否则返回0

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~

如果你想找到相同或不使用XOR的地方 在C:

#include <stdio.h>
int toBinary(unsigned int b1,unsigned int b2){
unsigned int b = b1 ^ b2;
printf("%x & %x = %x\n",b1,b2,b);
}
int main(){
int i,a,b;
unsigned int b1 = 0x100100;
unsigned int b2 = 0x010101;
toBinary(b1,b2);
return 0;
}