基于数组的位运算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倍, 但需要构造
表和实现多个函数, 对于小数组(几百字节以内)没有必要采用此算法.
大多数人首先想到的是首尾测试每个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倍, 但需要构造
表和实现多个函数, 对于小数组(几百字节以内)没有必要采用此算法.
相关文章推荐
- 基于数组的位运算4 位数组按bit位整体移动
- Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
- 基于数组的位运算1 数组位的基本运算
- 基于数组的位运算2 计算二进制1的个数
- 一种基于归并排序及随机数生成器对一个给定数组进行随机排列的算法
- matlab写数据到txt文件,C语言读取文件内容到数组@项目简介:基于PSS序列(频域)估计整数倍频偏
- 使用数组进行大数据运算
- 基于递归调用和链式结构的二叉树构建方法及其基本运算
- 基于proteus的51单片机仿真实例二十一、C语言的自增和自减运算演示实例
- 黑马程序员之C#编程基础学习笔记:将一个字符串数组的元素的顺序进行反转。
- 数组的4个基本操作:找出最大元素、平均值、复制、反转。
- 19.Selenium2 自动化测试实战-基于Python语言-数组与字典
- 第6节:scala中数组的操作运算
- 基于ARM的除法运算方法集锦
- 基于控制台的四则运算
- 1% 信号的基本运算:移位,反转,尺度变换
- 个人作业1--基于控制台的小学四则运算程序
- 几种基于膨胀和腐蚀的更高级运算
- 转贴: Kademlia: 基于异或运算的P2P信息系统
- 个人作业1——四则运算题目生成程序(基于java)