解题思路:
先分析一下题意,有a,b两个链表,要删除a链表内学号和b链表学号重复的节点,打印剩余节点数和其学号成绩。
因为只有学号和成绩,并且是一一对应的,所以我们可以用map来做,对map的查找和删除都很方便。
第一种方法(map):
#include <iostream> #include <map> using namespace std; int main() { map<int,int>p; int n,m,a,b; cin>>n>>m; //输入a链表数据 for(int i=0; i<n; i++) { cin>>a>>b; p[a]=b; } //在b链表输入的过程中进行对a链表的查找和删除操作 for(int i=0; i<m; i++) { cin>>a>>b; p.erase(a);//使用关键字删除 //使用迭代器删除 // auto t=p.find(a);//先查找 // if(t!=p.end())p.erase(t);//存在则删除 } //打印 cout<<p.size()<<endl; for(auto i:p) { cout<<i.first<<" "<<i.second<<endl; } return 0; }
如果自己实现Map的映射效果的话,就使用数组int p[10007],其中下标代表学号,p[学号]上存放成绩,先将数组初始化成-1,表示学号没有使用,当进行查找时,不是-1就说明a链表内存在该学号,重新记为-1表示删除。
第二种方法(数组映射):
#include <iostream> #include <cstring> using namespace std; int n,m,a,b,z;//z表示a中需要删除的节点数 int p[10007]; int main() { cin>>n>>m; memset(p, -1, sizeof(p));//初始化为-1(因为成绩不会有负数) //输入a链表数据 for(int i=0;i<n;i++){ cin>>a>>b; p[a]=b; } //输入b链表数据 for(int i=0;i<m;i++){ cin>>a>>b; //如果该学号上值不是-1,则记为-1表示删除 if(p[a]!=-1)p[a]=-1,z++; } //打印 cout<<n-z<<endl; for(int i=0;i<10007;i++){ if(p[i]!=-1)cout<<i<<" "<<p[i]<<endl; } return 0; }
当然,第二种方法是有缺陷的,这是假定了学号在10007以内,如果学号很大,就不能用数组表示了。
第三种方法,使用结构体,定义结构体数组,结构体内为学号和成绩,这样的缺点就是查找使用的时间较长。
第三种方法(结构体数组):
#include <iostream> using namespace std; struct pp{ int x,y;//学号,成绩(成绩为-1表示节点被删除) }p[107]; int n,m,a,b,z;//z表示被删除的节点数 void find(int a){ //查找,如果找到则记成绩为-1,表示删除 for(int i=0;i<n;i++){ if(p[i].x==a)p[i].y=-1,z++; } } int main() { cin>>n>>m; //输入a链表数据 for(int i=0;i<n;i++){ cin>>p[i].x>>p[i].y; } //输入b链表数据 for(int i=0;i<m;i++){ cin>>a>>b; find(a);//查找的过程中已删除 } cout<<n-z<<endl; for(int i=0;i<n;i++){ //成绩不是-1,则没有被删除 if(p[i].y!=-1)cout<<p[i].x<<" "<<p[i].y<<endl; } return 0; }
这三种方法中使用map是最方便的,数组映射比较简洁,结构体数组比较全面。
补充一下map的用法吧。
1,map简介
map是STL的一个关联容器,它提供一对一的hash。
第一个可以称为关键字(key),每个关键字只能在map中出现一次;
第二个可能称为该关键字的值(value);
map以模板(泛型)方式实现,可以存储任意类型的数据,包括使用者自定义的数据类型。Map主要用于资料一对一映射(one-to-one)的情況,map內部的实现自建一颗红黑树,这颗树具有对数据自动排序的功能。在map内部所有的数据都是有序的,后边我们会见识到有序的好处。比如一个班级中,每个学生的学号跟他的姓名就存在著一对一映射的关系。
2,查找元素,
当所查找的关键key出现时,它返回数据所在对象的位置,如果沒有,返回iter与end函数的值相同。
// find 返回迭代器指向当前查找元素的位置否则返回map::end()位置
iter = mapStudent.find("123");
if(iter != mapStudent.end())
cout<<"Find, the value is"<
else
cout<<"Do not Find"<<endl;
3,刪除与清空元素,
//迭代器刪除
iter = mapStudent.find("123");
mapStudent.erase(iter);
//用关键字刪除
int n = mapStudent.erase("123"); //如果刪除了會返回1,否則返回0
//用迭代器范围刪除 : 把整个map清空
mapStudent.erase(mapStudent.begin(), mapStudent.end());
//等同于mapStudent.clear()
4,map的大小,
在往map里面插入了数据,我们怎么知道当前已经插入了多少数据呢,可以用size函数,用法如下:
int nSize = mapStudent.size();
5,map的基本操作函数:
C++ maps是一种关联式容器,包含“关键字/值”对
begin() 返回指向map头部的迭代器
clear() 删除所有元素
count() 返回指定元素出现的次数, (帮助评论区理解: 因为key值不会重复,所以只能是1 or 0)
empty() 如果map为空则返回true
end() 返回指向map末尾的迭代器
equal_range() 返回特殊条目的迭代器对
erase() 删除一个元素
find() 查找一个元素
get_allocator() 返回map的配置器
insert() 插入元素
key_comp() 返回比较元素key的函数
lower_bound() 返回键值>=给定元素的第一个位置
max_size() 返回可以容纳的最大元素个数
rbegin() 返回一个指向map尾部的逆向迭代器
rend() 返回一个指向map头部的逆向迭代器
size() 返回map中元素的个数
swap() 交换两个map
upper_bound() 返回键值>给定元素的第一个位置
value_comp() 返回比较元素value的函数
总结节选自 C++ map用法总结(整理)
0.0分
4 人评分
C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:
一点编程也不会写的:零基础C语言学练课程
解决困扰你多年的C语言疑难杂症特性的C语言进阶课程
从零到写出一个爬虫的Python编程课程
只会语法写不出代码?手把手带你写100个编程真题的编程百练课程
信息学奥赛或C++选手的 必学C++课程
蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程
手把手讲解近五年真题的蓝桥杯辅导课程
发表评论 取消回复