您的位置:首页 > 其它

基于数组的位运算3 按bit位反转数组

2011-03-18 09:48 134 查看
  对于给定的数组uchar a[], 以及bit位长度(不是数组本身长度), 如何实现数组按位长度的反转算法, 效率一定要高哦

  大多数人首先想到的是首尾测试每个bit是否为0,1(本博客有关于如何测试,设置bit). 然后在交换bit位

这种算法的复杂度为位长度, 有没有办法进一步减小复杂度, 哪怕是常数因子也行,

  答案是有的, 请看下面详细代码描述, 基本思路是先构造一个16 bit的整数反转表

总体思想还是空间换时间, 毕竟没有免费的午餐.

typedef unsigned char uchar;

typedef unsigned short ushort;

typedef unsigned int uint;

//

//WordReverse[i] is equal to the bit reverse of i (i < 2^16)

static ushort WordReverse[1 << 16];

1. 下面先给出8bit整数按bit位反转实现

//reverse bit of a byte with binary representation

static uchar reverseByte(const uchar c)

{

//两个不同算法实现, 哪个性能更好取决于不同系统上的测试结果

#if 0

    return

        ((c * 0x80200802ULL) & 0x0884422110ULL) * 0x0101010101ULL >> 32;

#else

    uchar n =

        (c & 0x55) << 1 | (c & 0xAA) >> 1;

    n = (n & 0x33) << 2 | (n & 0xCC) >> 2;

    n = (n & 0x0F) << 4 | (n & 0xF0) >> 4;

    return n;

#endif   

}

2. 利用reverseByte函数构造 WordReverse

// init bit reverseByte of word table

void createWordReverseTable()

{  

    uchar bytereverse[256] = {0};

    nbitsize = sizeof(WordReverse) / sizeof(WordReverse[0]);

    for (i = 1; i < (1 << 8); i++)

        bytereverse[i] = reverseByte((uchar)i);

    for (i = 1; i < nbitsize; i++)

        WordReverse[i] = bytereverse[i >> 8] | (bytereverse[i & 255] << 8);

}

3. 实现反转长度为byte的数组, 也就是位长度为8整数倍的数组

//reverse word array bitarray with number of bitleng

static void reverseByteArray(uchar bitarray[], const int byteleng)

{

    //assert(bitleng % 8 == 0);

    ushort* ps = (ushort*)bitarray;

    ushort* pe = (ushort*)(bitarray + byteleng - 2);

    while (ps < pe) {

        const ushort tmp = WordReverse[*ps];

        *ps++ = WordReverse[*pe];

        *pe-- = tmp;

    }

    if (ps == pe) {

        *ps = WordReverse[*ps];

    } else if ((uchar*)pe + 1 == (uchar*)ps) {

        *((uchar*)ps) = WordReverse[*ps] >> 8;

    }

}

4. 反转bitleng长度的数组bitarray, 本问题的解决方案

static void reverseBitArray(uchar bitarray[], const int bitleng)

{

    const int bitremains = bitleng % 8;

    if (bitremains == 0) {

        //检测bitleng是否为8的倍数

        reverseByteArray(bitarray, bitleng / 8);

        return;

    }

    //bitleng补齐到8的倍数

    reverseByteArray(bitarray, (bitleng + 8 - bitremains) / 8);

    //多反转的bit, 数组整体向低地址移位

    shiftBitToLow(bitarray, bitleng + 16, 8 - bitremains);   

}

5. shiftBitToLow函数主要干什么的, 如何实现的?, 请看下回博文分解

结论:  问题给出, 和普通算法相比性能有多大的提升? 我的回答是性能>4倍, 但需要构造

表和实现多个函数, 对于小数组(几百字节以内)没有必要采用此算法.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  算法 测试 byte c