编程之美 2.19 区间重合判断

 区间重合判断:

比如,给出待判断区间[x,y](y>=x)如[1,6],以及目标区间[x1, y1],[x2,y2]....[xi, yi](如[2,3] [1,2] [3, 9]),  

 判断[1,6]是否在目标区间[2,3] [1,2] [3, 9]中 

 做法: 先把根据各个目标区间的第一个元素xi排序(可用快排),然后将目标区间中可以合并的区间进行合并,然后 在目标区间的xi中用二分查找来找待判断区间中的x,然后再判断y

排序的时间复杂度:O(NlogN )

合并排序时间复杂度:O(N)

单次查找的时间复杂度:O(logN )

 

代码如下:

#include<iostream>
#include<time.h>
#include<algorithm>
#include<cmath>
using namespace std;
struct position
{
	int high;
	int low;
};
bool operator <(position &a,position &b)
{
	return a.low<b.low;
}
bool operator ==(position &a,position &b)
{
	return (a.low==b.low)&&(a.high==b.high);
}
void Find(position &a,position b[],int start,int end)
{
	int mid;
	while (start<=end)
	{
		mid=(start+end)/2;
		if (a.low<=b[mid].high)
		{
			end=mid-1;
		}
		else
		{
			start=mid+1;
		}
	}
	if ((a.low>=b[mid].low)&&(a.high<=b[mid].high))
	{
		cout<<"源区间在目标区间中"<<endl;
	}
	else
	{
		cout<<"源区间不在目标区间中"<<endl;
	}
}
int main()
{
	position *D_temp;
	position *S_temp;
	int i;
	int last,cnt;//cnt表示合并后区间的总个数
	int N_d,N_s;
	N_s=1;
	S_temp=(position*)malloc(sizeof(position)*(N_s+1));
	cout<<"请输入目标区间的个数:";
	cin>>N_d;
	D_temp=(position*)malloc(sizeof(position)*(N_d+1));
	cout<<"请输入一个源区间:"<<endl;
	for (i=0;i<N_s;i++)
	{
		cin>>S_temp[i].low;
		cin>>S_temp[i].high;
	}
	cout<<"请输入目标区间:"<<endl;
	for (i=0;i<N_d;i++)
	{
		cin>>D_temp[i].low;
		cin>>D_temp[i].high;
	}
	//排序:O(NlogN)
	sort(D_temp,D_temp+N_d);
	cout<<endl;
	cout<<"对区间排序后:"<<endl;
	for (i=0;i<N_d;i++)
	{
		cout<<"[";
		cout<<D_temp[i].low;
		cout<<",";
		cout<<D_temp[i].high;
		cout<<"]";
		cout<<"   ";
	}
	cout<<endl;
	//合并 2 5 3 4
	cout<<"合并区间后:";
	last=D_temp[0].high;
	cnt=0;
	for (i=1;i<N_d;i++)
	{
		if (last>=D_temp[i].low)
		{
			if (last<=D_temp[i].high)
			{
				last=D_temp[i].high;
			} 
		}
		else
		{
			D_temp[cnt].high=last;
			last=D_temp[i].high;
			cnt++;
			D_temp[cnt].low=D_temp[i].low;
		}
	}
	D_temp[cnt++].high=last;
	cout<<endl;
	for (i=0;i<cnt;i++)
	{
		cout<<"[";
		cout<<D_temp[i].low;
		cout<<",";
		cout<<D_temp[i].high;
		cout<<"]";
		cout<<"   ";
	}
	cout<<endl;
	//查找
	Find(*S_temp,D_temp,0,cnt);
	return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值