习题7 给定一个非常长的字节序列(假设有十亿或万亿),如何高效的统计1的个数
方法一:(算法的时间复杂度就是1的个数)
[html] view plaincopy
//& 按位与 只要两个相同位同时为 1 则该位为 1
//7&5 0111 & 0101 = 0101 (5)
int OneCount(unsigned int x)
{
int count;
for(count=0; x>0; count++)
x&=x-1;//把最后面的1变0
return count;
}
方法二:
[html] view plaincopy
const int idx[256]={0,1,1,……,8}//0~255中含1的个数
int OneCount(unsigned int x)
{
int count=0;
for(; x>0; x>>=8)
count+=idx[x&255];
return count;
}
上面方法1利用的是把一个整数减去1,再和原来的整数做与运算,会把整数最右边一个1变为0。那么一个整数的二进制表示中就会少一个1,可以进行多少次这样的操作,那么整数中就有多少个1.
上面方法2中利用的是查表法,但是如果是建立一个有字节序列那么长的表肯定是不可行的,所以采用了滑动窗口的方法。取滑动窗口为256位,那么我们只需构造一个有256位的表就可以 了。
习题8 在程序中如何使用哨兵找出数组中的最大元素
#include "stdio.h"
int main()
{
int i;
int max;
int a[100];
for(i=0;i<100;++i)
a[i]=i;
i=0;
while(i<100)
{
max=a[i];
a[100]=max;
++i;
while(a[i]<max)//直到找到比刚才的大的元素
i++;
}
printf("%d\n",max);
return 0;
}