区间操作练习

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个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;
        }
    }

}



  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值