速度之巅——位图算法:
在很多面试题里面都会考到位图算法,那么什么是位图算法?简单来说就是一种用空间换时间,大大提高运算效率的一种方法。
首先请看一下下面的题:
在很多不重复整数中,这些整数的范围是0到40亿。输入一个数,判断这个数是不是属于这组整数。
一般来说这个很简单,做个for循环就可以,但是这个范围是40亿,范围很大需要的时间特别长。通过位图算法就可以解决这个问题。
假设整数范围是0到7,就用一个字节,里面有八个二进制位。把0到7依次排列,如下:
首先把字节都初始化为0,然后如果不重复的整数数组为(0,3,7),就把对应的这些为数改成1。如下:
这样所判断数除以8之后就知道在哪个字节了,除以8余就知道在哪个字节的什么位置,之后,判断这个位置是否为1,就知道是否存在这个数了。
具体代码如下:
#include<iostream>
#include<Windows.h>
using namespace std;
//导入数据函数
void init(char data[], int len) {
//假设能被三整除的数据都是要导入的数据
int n = len * 8;
int j = 0;
int m = 0;
for (int i = 0; i < n; i++) {
if (i % 3 == 0) {
j = (i/8);
m = (i % 8);
char *p = &data[0] + j; //寻找到在第多少字节
*p = *p | (1 << m); //寻找到在这个字节的多少位,进行传值
}
}
}
//算法实现
bool secnu(char data[],int len,unsigned int num) {
char *p = &data[0] + num/8;
bool ret= *p & (1 << (num%8));
return ret;
}
int main() {
unsigned int n = 400000000;
char *data;
int len = n / 8 + 1;
data = new char[len];
memset(data, 0, len); //把创建的空间初始为0
//导入数据
init(data, len);
//使用算法
unsigned int num;
while (1)
{
cout << "请输入要判断的数据(输入-1退出):";
cin >> num;
if (num == -1) {
break;
}
if (secnu(data, len, num)) {
cout << "输入数据包含在里面" << endl;
}
else {
cout << "输入数据没有包含在里面" << endl;
}
}
system("pause");
return 0;
}