如何进行按字典顺序的比较

时间:2019-06-09 10:36:03

标签: gcc compare bitwise-operators lexicographic

gcc编译器将char数据类型解释为整数,这很有意义...有一个比较函数可以将其比较为位字符串吗?

  char a='0';  
  char b= 0b11111111;
  if (a<b) {/* never goes here! */}
  if (bitStringCompare(a,b)) {/* this kind of "native" function exists? */}

解决我的现实生活问题的一种更好方法是使用其他数据类型声明ab,例如,实际上是一个字符串(假设){ {3}},但我看不到按位词典的比较。


注释

可变长度位串的字典顺序为:
0 <00 <01 <1 <10 <{{1 }}
其中所有项目都是位字符串(例如11,但具有0!= 00),它们不是ASCII字符串。
对于数学家来说,使用ASN1TDynBitStr,每个字符串都是一个包含2个字母的字母单词。

0b10似乎不是解决方案,因为它不是按位定向的。

重要:我需要良好的性能,因此(对于我的应用程序)将位转换为ASCII std::lexicographical_compare0无效。我需要进行快速逐位词典比较。


建议(构想最佳解决方案):将大位字符串划分为 n 个大块(例如,tham大于32位,tham小于1024位)时,使用< em> i = 0到 n -1 ...也许更快的方法是一次使用块(例如32位的Chunck 1)函数检查x_i,它们(当a_i==b_i时)使用一次位函数返回a_i!=b_i

在连接位a_i<b_i时,数字(无符号)数据类型可以使用位串字典比较a_i==b_i:例如,为了比较1,我们可以使用0000==0 == 0b10000

2 个答案:

答案 0 :(得分:1)

最简单的方法是将位叠加在无符号类型上(例如unsigned char而不是char)。如果该类型可以存储W位(在char的情况下为8),则可以使用以下地址寻址nth

nth_bit(array,nth) array[nth/W]&(1ull<<(nth%W))

然后最简单的方法来进行字典上的位比较 从左边开始,然后从左到右lexicographically comparing遍历各个位,就像遍历字符串中的字符一样。

可以通过一次比较几个位来加快这种方法的速度,但是随后您必须注意事情是如何对齐的。

答案 1 :(得分:0)

这是一个Wiki,请编辑(!)并补充答案。


此片段显示可以优化:

  1. 通过基准测试选择块长度(大约8位,16位或32位),以进行更快的按位比较。
  2. 仅使用按位比较一次,所有其他均等同于块。

假设@PSkocik bitwise comparison中的最佳性能是每块8位(字符),并假设我们通过长整数来馈送数据,

  #include <stdio.h>
  #include <string.h>
  #include <stdint.h>

  union Data {
    uint64_t i;  // unsigned long long
    char str[8]; // 8bits*8=64bits
  };

  int main( ) {
    int kmax = 6;
    union Data x[6] = {
      [0].i=0b0000000000000000000000000000000000000000000000000000000000000010,
      [1].i=0b1000000000000000000000000000000000000000000000000000000000000000,
      [2].i=0b0000000000000000000000000000000000000000000000000000000000000101, //
      [3].i=0b0000000000000000000000000000000001000000000000000000000000000011,
      [4].i=0b0000000000000000000000000000000000000000000000000000000000000110,
      [5].i=0b0000000000000000000000000000000000000000000000000000000000000111
    };
    printf( "\nComparing all with x[2], %zu bytes/item\n", sizeof(x[2]));
    for (int k=0; k<kmax; k++) {
      printf( "\nx[%d]: i=%ju\n\t", k, x[k].i);
      for (int j=7;j>=0;j--) {
        printf( " %d(%s)", j, (x[k].str[j]==x[2].str[j])? "=": "≠" );
      }
    }
    printf("\n");
    return 0;
  }

输出:

Comparing all with x[2], 8 bytes/item

x[0]: i=2
     7(=) 6(=) 5(=) 4(=) 3(=) 2(=) 1(=) 0(≠)
x[1]: i=9223372036854775808
     7(≠) 6(=) 5(=) 4(=) 3(=) 2(=) 1(=) 0(≠)
x[2]: i=5
     7(=) 6(=) 5(=) 4(=) 3(=) 2(=) 1(=) 0(=)
x[3]: i=1073741827
     7(=) 6(=) 5(=) 4(=) 3(≠) 2(=) 1(=) 0(≠)
x[4]: i=6
     7(=) 6(=) 5(=) 4(=) 3(=) 2(=) 1(=) 0(≠)
x[5]: i=7
     7(=) 6(=) 5(=) 4(=) 3(=) 2(=) 1(=) 0(≠)