1问题:
允许两个操作,add(min,max)和del(min,max),一开始区间内为空,每个操作后算出区间内的集合,要求能自动合并、拆分集合。例如:
操作1:add(1,7) 区间内的集合:(1,7)
操作2:add(9,10) 区间内的集合:(1,7)、(9,10)
操作3:del(3,5) 区间内的集合:(1,2)、(6,7)、(9,10)
操作4:add(3,8) 区间内的集合:(1,10)
整个区间的范围可能会在(0,2^32-1)之间。
要求给出add()和del()的算法描述和代码实现,程序要实现输入输出即可供用户操作,实现对应命令,统一确定输出命令的格式为
add number1 number2
del number1 number2
stop
比如
add 1 7
(1,7)
del 3 5
(1,2)、(6,7)
stop
程序结束
2.思路
1.因为范围是0到2^32-1,因此直接用int加数据结构来表示区间,至少要用到4*2^32byte的内存空间也就是16G,明显不能这么做
2.在想这是区间操作,又是连续的,区间只有两种状态,一种为空,一种为存在,恰好对应一个位的两种状态,这样就自然而然的想到了用位图的方法,可以
3.既然想到用位图了,就比较好做了,一切水到渠成,首先定义几个位操作的宏函数,然后定义区间操作的宏函数,然后在这个基础上用函数加一些包裹
3.代码如下
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
//思路用位进行操作,每一位代表一个整数
#define LEN_8 536870912 //2^32/8
#define LEN_32 134217728
#define MAX 4294967295 //2^32-1
#define MASK 0x1f //5个1
unsigned int S[LEN_32]={0};
#define set_bit_false(num) S[num>>5]=S[num>>5]&~(1<<(num&31))
#define set_bit_true(num) S[num>>5]=(S[num>>5])|(1<<(num&31))
#define bit_is_true(num) S[num>>5]&(1<<(num&31))
#define hash_bit_true(num1,num2) while(num1<=num2){set_bit_true(num1);num1++;}
#define hash_bit_false(num1,num2) while(num1<=num2){set_bit_false(num1);num1++;}
void str_aly(char *s,char*fuc,unsigned int* num1,unsigned int* num2);
void add(unsigned int num1,unsigned int num2)
{
hash_bit_true(num1,num2);
}
void del(unsigned int num1,unsigned int num2)
{
hash_bit_false(num1,num2);
}
void print(unsigned int input_max)
{
unsigned int num=0;
unsigned int index1=0,index2=0;
int flag=0;
while(num<=input_max)
{
if(bit_is_true(num)&&!flag)
{
index1=num;
flag=1;
}
else if(bit_is_true(num)&&flag)
{
index2=num;
}
else if(!(bit_is_true(num))&&flag)
{
flag=0;
if(index2==0) printf("(%d,%d)\t",index1,index1);
else
{
printf("(%d,%d)\t",index1,index2);
}
index1=index2=0;
}
num++;
}
printf("\n");
}
void stop()
{
exit(0);
}
int main()
{
unsigned int input_max=0;
unsigned int num1=0,num2=0;//输入的区间
int len=(int)pow(2.0,30)/8;
//int len=(int)pow(2,32)-1;
// printf("len=%d/n",len);
char s[20];
char fuc[30]={'0',};
while(1)
{
//清空fuc里面的缓存
int i=0;
for(i=0;i<5;i++)
{
*(fuc+i)=0;
}
printf("请输入数据\n\t");
gets(s);
str_aly(s,fuc,&num1,&num2);
if(input_max<num2+1)
{
input_max=num2+1;
}
if(strcmp("add",fuc)==0)
{
add(num1,num2);
}
else if(strcmp("del",fuc)==0)
{
del(num1,num2);
}
else if(strcmp("stop",fuc)==0)
{
stop();
}
else if(strcmp("print",fuc)==0)
{
print(input_max);
}
num1=num2=0;
//puts(s);
}
return 0;
}
void str_aly(char *s,char*fuc,unsigned int* num1,unsigned int* num2)
{
int flag=1;
while(*s)
{
if(*s!=' '&&flag==1)
{
*fuc=*s;
s++;
fuc++;
}
else if(*s==' '&&flag==1)
{
flag=2;
s++;
}
else if(*s!=' '&&flag==2)
{
*num1=*num1*10+*s-'0';
s++;
}
else if(*s==' '&&flag==2)
{
flag=3;
s++;
}
else if(*s!=' '&&flag==3)
{
*num2=*num2*10+*s-'0';
s++;
}
else if(*s==' '&&flag==3)
{
break;
}
}
}