区间操作练习

来源:互联网 发布:知乎 pocket 编辑:程序博客网 时间:2024/06/10 01:12

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

print

stop

比如

add 1 7

print

(1,7)

del 3 5

print

(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个1unsigned 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;        }    }}



0 0