项目题目2——数据结构与算法

接上次的题目,这是考试的第二题

第一题在这里:项目题目1——字符串相关操作-CSDN博客


数据结构与算法(多键值排序)

无线基站邻区关系缓存表维护

无线通信移动性需要在基站上配置邻区(本端基站的小区LocalCell与周边邻基站的小区NeighborCell映射)关系,为了能够加速无线算法的计算效率,设计一个邻区关系缓存表,用于快速地通过本小区LocalCell查询到邻小区NeighborCell。但是缓存表有一定的规格限制,因此到达规格并且需要插入新的数据时,需要删除邻区数据,选择删除邻区数据对象的策略为:

1)使用次数最少的;

2)如果1)返回有多个对象,则选择最久未使用的。

请设计并实现一个满足以上要求的数据结构和算法实现

输入

1.首行以字符“capacity:”标识设置一个整数容量;

2.以“write:”标识开始进行若干组[LocalCell,NeighborCell]邻区数据的输入,每组数据为一行;如果“write:”已经存在的LocalCell数据,更新其对应的NeighborCell,并刷新使用时间和次数+1;如果某邻区数据被删除,缓存表不再保留其记录;

3.以“read:”标识进行一次读取LocalCell的使用操作,刷新使用时间和次数+1;

4.最后以“query:”标识查询输出操作,输入正整数LocalCell,查询NeighborCell;

注:

1)写入和读取都表示对LocalCell的使用操作;

2)capacity、LocalCell和NeighborCell都是正整数,范围在[1,10000];

3)输入的总行数不超过30000行。

输出 

每个查询输入正整数LocalCell对应NeighborCell,表示在邻区关系缓存表中的记录。

1.找到,返回NeighborCell;

2.没有找到,返回-1。

此次没有写其他函数,直接在主函数里面完成了操作

很神奇,这道题90行左右,代码量是第一题的1/3 

数据结构

用vector,所谓的动态数组存储write:的值

(LocalCell、NeighborCell各一个数组,二者下标对应,同时操作)

这时,你肯定想问了,为啥不用map或者哈希表存储呢?

因为map是按序存放,哈希表随机存放;那么我对于进入的顺序就不得而知了,以及此题考查更新的位置,那还是用有序的数组比较合适。

map<int,int>cnt 存储localcell与其访问次数

比较值得推敲的是,在判断该删除哪个数据时候的操作,具体看write:中的操作;

read:就更新访问的数据在最新的位置(最后面)cnt记录++。

解题代码

#include<iostream>
#include<cstring>
#include <map>
#include<vector>
using namespace std;
int main() {
	vector<int> localcell;
	vector<int> neicell; 
	map<int,int> cnt;//记录localcell值以及访问次数 
	int capacity = 0;//容量初始化
	int now = 0;//记录现在的容量 初始化为0 
	string str;//输入的值 
	while(1) {
		cin>>str;
		if(str=="capacity:") {
			cin>>capacity;
		}
		else if(str=="write:"){
			int tmp;
			cin>>tmp;
			int a,b;
			for(int i=0;i<tmp;i++){
				cin>>a;
				cin>>b;
				for(int j=0;j<localcell.size();j++){
					if(a==localcell[j]){
						localcell.erase(localcell.begin()+j);
						neicell.erase(neicell.begin()+j);
						now--;
						break;
					}
				}
				localcell.push_back(a) ; 
				neicell.push_back(b) ;
				cnt[a]++;
			}
			now += tmp;
			
			if(now>capacity){//输入的数据量大于容量的时候 
				//判断要删除的对象 1.访问次数(cnt)最少的情况 2.最久未更新 
				int need = now-capacity;//需要删除的元素个数 
				int er = localcell[0];//要删除元素的localcell值 
				while(need){
					for(int i=1;i<now-tmp;i++) {
						er = cnt[er] <= cnt[localcell[i]] ? er : localcell[i];
					}
					for(int i=0;i<localcell.size() ;i++){
						if(localcell[i]==er){
							localcell.erase(localcell.begin()+i);
							neicell.erase(neicell.begin()+i);							
						}
					}
					cnt.erase(er);
					need--;
					now--;
				}
			}
		}
		else if(str=="read:"){
			int num;
			cin>>num;
			for(int i=0;i<now;i++){//更新位置在最后面 
				if(localcell[i]==num){
					cnt[num]++;//访问次数+1 
					localcell.erase(localcell.begin()+i);
					localcell.push_back(num);
					int a;
					a = neicell[i];
					neicell.erase(neicell.begin()+i);
					neicell.push_back(a);
				}	
			}
			 
		}
		else if(str=="query:"){
			int n;
			int flag = 0; 
			cin>>n;
			for(int i=0;i<now;i++){
				if(localcell[i] == n){
					cout<<neicell[i]<<endl;
					flag = 1;
					break;
				}
			}
			if(flag == 0){
				cout<<-1<<endl;
			}
			break;
		}
	}

	return 0;
	
}

用例输入

样例1

输入:

capacity:
3
write:
3
1 2
4 3
2 3
read:
2
write:
1
3 1
query:
1

输出:

-1

解释:

1.设定容量capacity为3;

2.write输入3组数据;

3.read读取2使用,刷新该邻区对使用时间和次数;

4.再write输入1组数据,因为已经超过了容量3,所以把最早输入且未使用的数据“1 2”去除;

5.最后进行query查询1,因为已经删除,所以返回-1。

 

样例2

输入:

capacity:
4
write:
5
3 5
1 2
4 3
2 3
5 4
read:
4
read:
1
read:
2
read:
5
write:
1
6 1
query:
1

输出:

2

解释:

1.设定容量capacity为4;

2.write输入5组数据,因为容量为4,最早输入的数据“3 5”被删除;

3.read依次先后读取4、1、2、5,刷新该邻区对使用时间和次数;

4.再write输入1组数据,因为已经超过了容量4,需要选择删除邻区的数据对象,四组邻区对象使用次数一样,所以把最久未使用的数据“4 3”去除;

5.最后进行query查询1,返回2。

 

样例3

输入:

capacity:
3
write:
5
3 5
1 2
1 3
2 4
5 4
read:
5
write:
1
6 1
query:
1

输出:

3

解释:

1.设定容量capacity为3;

2.write输入5组数据,其中“1 3”会把“1 2”替换掉,并更新访问次数;因为容量为3,最早数据“3 5”去除;

3.read读取5,刷新该邻区对使用时间和次数;

4.再write输入1组数据,因为已经超过了容量3,选择删除邻区数据对象,把最久未使用的数据“2 4”去除;

5.最后进行query查询1,返回3。

 

不知道具体操作的可以加上这段代码,输出对应值: 

cout<<capacity<<' '<<"now="<<now<<endl;
	for(int i=0;i<now;i++){
				cout<<"localcell"<<i<<" = "<<localcell[i]<<endl;
				cout<<"neicell"<<i<<" = "<<neicell[i]<<endl;
			}
	
	for(auto it = cnt.begin() ;it!=cnt.end() ;++it) {
		cout<<"cnt"<<it->first<<" : "<<it->second<<endl;
	}

 例如样例3:


通过这道题,让我更加熟悉对map、vector的内置函数的使用,也需要注意循环break;的问题;

第二题考试时候完成用例87%,估计有什么神奇的用例没有考虑到;

不知道这次写好的能不能AC;

继续加油啦!

  • 60
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值