【程设の旅】STL作业 Ⅱ
Ciallo~(∠・▽< )⌒☆
啊不对我不是柚子厨
今天过来更新第13次作业的代码
刚好五一比较有空
下面我们看题:
A:List
描述
写一个程序完成以下命令:
new id ——新建一个指定编号为id的序列(id < 10000)
add id num——向编号为id的序列加入整数
num merge id1 id2——如果id1等于id2,不做任何事,否则归并序列id1和id2中的数,并将id2清空
unique id——去掉序列id中重复的元素
out id ——从小到大输出编号为id的序列中的元素,以空格隔开
输入
第一行一个数n,表示有多少个命令( n<=200000)。以后n行每行一个命令。
输出
按题目要求输出。
样例输入
16
new 1
new 2
add 1 1
add 1 2
add 1 3
add 2 1
add 2 2
add 2 3
add 2 4
out 1
out 2
merge 1 2
out 1
out 2
unique 1
out 1
样例输出
1 2 3
1 2 3 4
1 1 2 2 3 3 4
1 2 3 4
Solution
其实题目没有强求你用题干的数据结构就是了
但是我们这题还是用list,虽然这题用multimap或者multiset也可以的
那题目中的指令就变成:
new 其实也没啥用
add 就是push_back
merge 就是merge
unique 就是先sort后unique(有点像离散化?不过方便输出也是了)
out 就是用迭代器输出 使用更方便的auto而不是iterator
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define maxn 200005
using namespace std;
int n;
list<int>ma[maxn];
string s;
int id,num;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>s;
if(s[0]=='n'){
cin>>id;
}
else if(s[0]=='a'){
cin>>id>>num;
ma[id].push_back(num);
}
else if(s[0]=='m'){
cin>>id>>num;
if(id==num) continue;
else{
ma[id].merge(ma[num]);
}
}
else if(s[0]=='u'){
cin>>id;
ma[id].sort();
ma[id].unique();
}
else if(s[0]=='o'){
cin>>id;
if(ma[id].empty()) cout<<endl;
else{
ma[id].sort();
for(auto i=ma[id].begin();i!=ma[id].end();i++){
cout<<*i<<' ';
}
cout<<endl;
}
}
}
system("pause");
return 0;
}
B RPN Calculator
描述
逆波兰表示法(或简称 RPN),与相关的波兰表示法类似,波兰表示法是波兰数学家扬・武卡谢维奇(Jan Łukasiewicz)于 1920 年引入的一种前缀表示法。逆波兰表示法是一种数学表示法,其中每个运算符都紧跟在其所有操作数之后。它也被称为后缀表示法。
在逆波兰表示法中,运算符紧跟在操作数之后;例如,要计算 3 加 4 ,应写成 “3 4 +”,而不是 “3 + 4”。如果有多个运算,运算符会紧跟在第二个操作数之后;所以常规中缀表示法下写成 “3 - 4 + 5” 的表达式,在逆波兰表示法中应写成 “3 4 - 5 +” :先计算 3 减 4 ,然后再加上 5。逆波兰表示法的一个优点是它无需中缀表示法中所需的括号。“3 - 4 * 5” 也可以写成 “3 - (4 * 5)” ,但这与 “(3 - 4) * 5” 的含义截然不同,只有括号能区分这两种不同的含义。在后缀表示法中,前者应写成 “3 4 5 * -” ,它明确表示 “3 (4 5 ) -” 。
你需要设计一个简单的逆波兰表示法计算器,该计算器需支持 “+”、“-”、“”、“/”(除数的绝对值不小于 10⁻⁹ )和 “^”(幂运算符,若底数 b≤0 ,指数 e 必须是不大于 10⁹ 的正整数 )运算符。可以假设计算过程中的所有数字都可以用双精度浮点数表示。
此外,我们的计算器有一定的内存。每次计算一个表达式时,内存中最小的数字将被删除,并替换为该表达式的值。
输入
第一行包含一个整数 n,它是我们计算器的内存大小。
从第二行开始,将给出 n 个数字,这些是内存的初始值。除最后一行外,每行将有 10 个数字。
然后每行是一个有效的逆波兰表示法表达式,以 “=” 结尾,“=” 是计算命令。每个项的长度不超过 20 个字符。
输出
对于每个表达式,在一行中输出其值。
然后输出一个空行,将两部分内容分隔开。
最后,按升序输出内存中的所有数字,每行 10 个数字。
每个数字应采用科学计数法格式,保留 6 位小数,指数部分占 2 位,类似于 C 语言中 printf () 函数的 “% e” 格式字符串。一行中的数字之间用空格分隔。
样例输入
4
1e6 1e-6 0.001 1000
1 2 + 3 4 + * =
1 0.1 / 8 ^ =
样例输出
2.100000e+01
1.000000e+08
2.100000e+01 1.000000e+03 1.000000e+06 1.000000e+08
提示
Huge input, scanf() is recommended
%e格式输出在windows环境下指数部分为3位,在系统的测试环境下为2位。
Solution
逆波兰表达式的求法应该都会?用一个栈很简单
然后,有什么要介绍的呢
啊,就是这个atof(x.c_str())
其中,c_str()指的是将string类型变量x转换成char类型变量
然后,atof()表示将char型变量转换成双精度浮点数
这部分来自网络代码
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&(-x))
using namespace std;
int n;
int main(){
cin>>n;
stack<double>ma;
multiset<double>res;
for(int i=1;i<=n;i++){
double x;
cin>>x;
res.insert(x);
}
string x;
while(cin>>x){
if(x=="="){
double s=ma.top();
printf("%e\n",s);
ma.pop();
auto it=res.begin();
res.erase(it);
res.insert(s);
}
else if(x=="+"||x=="-"||x=="*"||x=="/"||x=="^"){
double a,b,c;
a=ma.top();
ma.pop();
b=ma.top();
ma.pop();
if(x=="+"){
c=a+b;
}
else if(x=="-"){
c=b-a;
}
else if(x=="*"){
c=a*b;
}
else if(x=="/"){
c=b/a;
}
else{
c=pow(b,a);
}
ma.push(c);
}
else{
double num;
num=atof(x.c_str());
ma.push(num);
}
}
cout<<endl;
int count=0;
for(auto it=res.begin();it!=res.end();it++){
count++;
if(count%10==0){
printf("%e\n",*it);
}
else{
printf("%e ",*it);
}
}
system("pause");
return 0;
}
C:Set
描述
现有一整数集(允许有重复元素),初始为空。我们定义如下操作:
add x 把x加入集合
del x 把集合中所有与x相等的元素删除
ask x 对集合中元素x的情况询问
对每种操作,我们要求进行如下输出。
add 输出操作后集合中x的个数
del 输出操作前集合中x的个数
ask 先输出0或1表示x是否曾被加入集合(0表示不曾加入),再输出当前集合中x的个数,中间用空格格开。
输入
第一行是一个整数n,表示命令数。0<=n<=100000。
后面n行命令,如Description中所述。
输出
共n行,每行按要求输出。
样例输入
7
add 1
add 1
ask 1
ask 2
del 2
del 1
ask 1
样例输出
1
2
1 2
0 0
0
2
1 0
提示
Please use STL’s set and multiset to finish the task
Solution
由于题目中需要我们删除重复元素,所以必须用到multiset 然后,我们用set来记录x是否被加入过集合就可以
至于删除操作,我们用一个循环find就能实现
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n;
multiset<int>ma;
set<int>k;
string s;
int x;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>s>>x;
if(s[1]=='d'){
ma.insert(x);
k.insert(x);
cout<<ma.count(x)<<endl;
}
else if(s[1]=='e'){
cout<<ma.count(x)<<endl;
auto it=ma.find(x);
while(it!=ma.end()){
ma.erase(it);
it=ma.find(x);
}
}
else{
if(k.find(x)!=k.end()) cout<<1<<' ';
else cout<<0<<' ';
cout<<ma.count(x)<<endl;
}
}
system("pause");
return 0;
}
D:字符串操作
描述
给定n个字符串(从1开始编号),每个字符串中的字符位置从0开始编号,长度为1-500,现有如下若干操作:
copy N X L:取出第N个字符串第X个字符开始的长度为L的字符串。
add S1 S2:判断S1,S2是否为0-99999之间的整数,若是则将其转化为整数做加法,若不是,则作字符串加法,返回的值为一字符串。
find S N:在第N个字符串中从左开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。
rfind S N:在第N个字符串中从右开始找寻S字符串,返回其第一次出现的位置,若没有找到,返回字符串的长度。
insert S N X:在第N个字符串的第X个字符位置中插入S字符串。
reset S N:将第N个字符串变为S。
print N:打印输出第N个字符串。
printall:打印输出所有字符串。
over:结束操作。
其中N,X,L可由find与rfind操作表达式构成,S,S1,S2可由copy与add操作表达式构成。
输入
第一行为一个整数n(n在1-20之间)
接下来n行为n个字符串,字符串不包含空格及操作命令等。
接下来若干行为一系列操作,直到over结束。
输出
根据操作提示输出对应字符串。
样例输入
3
329strjvc
Opadfk48
Ifjoqwoqejr
insert copy 1 find 2 1 2 2 2
print 2
reset add copy 1 find 3 1 3 copy 2 find 2 2 2 3
print 3
insert a 3 2
printall
over
样例输出
Op29adfk48
358
329strjvc
Op29adfk48
35a8
提示
推荐使用string类中的相关操作函数。
Solution
我们要明确的一点是,这道题可能存在嵌套的函数,所以应该使用没有参数值的函数来实现,因为如果有参数值确实不好处理这个东西的类型,写模版确实麻烦多了
这道题思路有参考网络
其中,stoi表示将string型变量转成int型变量
to_string表示将int型变量转成string型变量
npos通常用于表示查找失败或者末尾
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&(-x))
#define maxn 25
using namespace std;
string Copy();
string Add();
bool isnum(string x);
int Find();
int Rfind();
string Insert();
string Reset();
void Print(int x);
void Printall();
int n0;
string str[maxn];
int tot;
string Copy(){
string N,X,L;
int n,x,l;
cin>>N;
if(N=="find"){
n=Find();
}
else if(N=="rfind"){
n=Rfind();
}
else n=stoi(N);
cin>>X;
if(X=="find"){
x=Find();
}
else if(X=="rfind"){
x=Rfind();
}
else x=stoi(X);
cin>>L;
if(L=="find"){
l=Find();
}
else if(L=="rfind"){
l=Rfind();
}
else l=stoi(L);
string temp=str[n].substr(x,l);
return temp;
}
string Add(){
string S1,S2,s1,s2;
cin>>S1;
if(S1=="copy"){
s1=Copy();
}
else if(S1=="add"){
s1=Add();
}
else s1=S1;
cin>>S2;
if(S2=="copy"){
s2=Copy();
}
else if(S2=="add"){
s2=Add();
}
else s2=S2;
if(isnum(s1)&&isnum(s2)){
int a=stoi(s1),b=stoi(s2);
return to_string(a+b);
}
else return s1+s2;
}
bool isnum(string x){
int l=x.length();
if(l>=5) return false;
bool flag=true;
for(int i=0;i<=l-1;i++){
if(!(x[i]>='0'&&x[i]<='9')){
flag=false;
break;
}
}
return flag;
}
int Find(){
string S,N,s;
int n;
cin>>S;
if(S=="copy"){
s=Copy();
}
else if(S=="add"){
s=Add();
}
else s=S;
cin>>N;
if(N=="find"){
n=Find();
}
else if(N=="rfind"){
n=Rfind();
}
else n=stoi(N);
int temp;
if(str[n].find(s)!=string::npos){
temp=str[n].find(s);
}
else temp=str[n].size();
return temp;
}
int Rfind(){
string S,s,N;
int n;
cin>>S;
if(S=="copy"){
s=Copy();
}
else if(S=="add"){
s=Add();
}
else s=S;
cin>>N;
if(N=="find"){
n=Find();
}
else if(N=="rfind"){
n=Rfind();
}
else n=stoi(N);
int temp;
if(str[n].rfind(s)!=string::npos){
temp=str[n].rfind(s);
}
else temp=str[n].size();
return temp;
}
string Insert(){
string N,X,S,s;
int n,x;
cin>>S;
if(S=="copy"){
s=Copy();
}
else if(S=="add"){
s=Add();
}
else s=S;
cin>>N;
if(N=="find"){
n=Find();
}
else if(N=="rfind"){
n=Rfind();
}
else{
n=stoi(N);
}
cin>>X;
if(X=="find"){
x=Find();
}
else if(X=="rfind"){
x=Rfind();
}
else x=stoi(X);
string temp=str[n].insert(x,s);
return temp;
}
string Reset(){
string S,s,N;
int n;
cin>>S;
if(S=="copy"){
s=Copy();
}
else if(S=="add"){
s=Add();
}
else s=S;
cin>>N;
if(N=="find"){
n=Find();
}
else if(N=="rfind"){
n=Rfind();
}
else n=stoi(N);
swap(str[n],s);
return str[n];
}
void Print(int x){
cout<<str[x]<<endl;
return ;
}
void Printall(){
for(int i=1;i<=n0;i++){
cout<<str[i]<<endl;
}
return ;
}
int main(){
cin>>n0;
for(int i=1;i<=n0;i++){
cin>>str[i];
}
while(1){
string op;
cin>>op;
if(op=="over") break;
else if(op=="copy"){
Copy();
}
else if(op=="add"){
Add();
}
else if(op=="find"){
Find();
}
else if(op=="rfind"){
Rfind();
}
else if(op=="insert"){
Insert();
}
else if(op=="reset"){
Reset();
}
else if(op=="print"){
int x;
cin>>x;
Print(x);
}
else if(op=="printall"){
Printall();
}
}
system("pause");
return 0;
}
E:热血格斗场
描述
为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。
我们假设格斗的实力可以用一个正整数表示,成为实力值。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有两个人的实力值与他差别相同,则他会选择比他弱的那个(显然,虐人必被虐好)。
不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。
输入
第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。输入保证两人的实力值不同。
输出
N行,每行两个数,为每场比赛双方的id,新手的id写在前面。
样例输入
3
2 1
3 3
4 2
样例输出
2 1
3 2
4 2
Solution
本题要求我们匹配比赛记录
那么,我们可以采用multimap
为什么是multimap?因为这道题其实用multiset好像也可以,但是就直接用multimap吧,因为可能有的数的power是一样的
代码实现还是不难的
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n;
int id,p;
multimap<int,int>lst;
int main(){
scanf("%d",&n);
lst.insert(make_pair(1000000000,1));
for(int i=1;i<=n;i++){
cin>>id>>p;
auto it=lst.insert(make_pair(p,id));
cout<<id<<' ';
if(it!=lst.begin()&&it!=--lst.end()){
auto it_1=it;
auto it_2=it;
it_1--;
it_2++;
if(abs(it_1->first-p)<=abs(it_2->first-p)){
cout<<it_1->second<<endl;
}
else cout<<it_2->second<<endl;
}
else if(it==lst.begin()){
cout<<(++it)->second<<endl;
}
else if(it==--lst.end()){
cout<<(--it)->second<<endl;
}
}
system("pause");
return 0;
}
F:冷血格斗场
描述
为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家冷血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。
我们假设格斗的实力可以用一个非负整数表示,称为实力值,两人的实力值可以相同。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有多个人的实力值与他差别相同,则他会选择id最小的那个。
不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。
输入
第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。
输出
N行,每行两个数,为每场比赛双方的id,新手的id写在前面。
样例输入
3
2 3
3 1
4 2
样例输出
2 1
3 2
4 2
Solution
本题的重点在于,如果有多个人的实力值和他相同,那么,它会选择id最小的那个
意思是,对于后输入的,如果后输入的id比前面的小,那么前面的就没有意义了(有点像优先队列?)
所以,我们只需维护一个map,因为在上述说法下不会存在冲突
下面看代码:
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
using namespace std;
int n,id,p;
map<int,int>ma;
int main(){
scanf("%d",&n);
ma[1000000000]=1;
for(int i=1;i<=n;i++){
cin>>id>>p;
cout<<id<<' ';
auto it=ma.find(p);
if(it!=ma.end()) {
cout<<ma[p]<<endl;
ma[p]=min(id,ma[p]);
continue;
}
else ma[p]=id;
it=ma.find(p);
if(it!=ma.begin()&&it!=--ma.end()){
auto it_1=it;
auto it_2=it;
it_1--;
it_2++;
if(abs(it_1->first-p)<abs(it_2->first-p)){
cout<<it_1->second<<endl;
}
else if(abs(it_1->first-p)==abs(it_2->first-p)){
cout<<min(it_1->second,it_2->second)<<endl;
}
else cout<<it_2->second<<endl;
}
else if(it==ma.begin()){
cout<<(++it)->second<<endl;
}
else if(it==--ma.end()){
cout<<(--it)->second<<endl;
}
}
system("pause");
return 0;
}
G:Priority_queue 练习题
描述
我们定义一个正整数a比正整数b优先的含义是:
*a的质因数数目(不包括自身)比b的质因数数目多;
*当两者质因数数目相等时,数值较大者优先级高。
现在给定一个容器,初始元素数目为0,之后每次往里面添加10个元素,每次添加之后,要求输出优先级最高与最低的元素,并把该两元素从容器中删除。
输入
第一行: num (添加元素次数,num <= 30)
下面10*num行,每行一个正整数n(n < 10000000).
输出
每次输入10个整数后,输出容器中优先级最高与最低的元素,两者用空格间隔。
样例输入
1
10 7 66 4 5 30 91 100 8 9
样例输出
66 5
Solution
本题没叫你用优先队列,那你可以不用啊哈哈
所以我们用set来完成 虽然multiset也可以,但是set可以去除不必要的元素,所以使用set
同样,这里要说明的是,我们到目前使用仿函数还是比较少的,所以这里要注意一下
然后就是仿函数类这里要注意,要加上一个const 因为新版本编译器要求更为严格,需要cmp通过静态函数变量形式被调用,所以不加const会报错
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define lowbit(x) (x&(-x))
using namespace std;
bool isprime(int x){
if(x==1) return false;
if(x==2) return true;
for(int i=2;i*i<=x;i++){
if(x%i==0) return false;
}
return true;
}
int count(int x){
int ans=0;
for(int i=1;i<x;i++){
if(x%i!=0) continue;
if(isprime(i)) ans++;
}
return ans;
}
struct node{
int num,rnum;
};
struct cmp{
bool operator()(const node a,const node b)const{
if(a.rnum==b.rnum) return a.num<b.num;
return a.rnum<b.rnum;
}
};
int main(){
int n,k;
cin>>n;
set<node,cmp>queue;
for(int i=1;i<=n;i++){
for(int j=1;j<=10;j++){
cin>>k;
node a;
a.num=k;
a.rnum=count(k);
queue.insert(a);
}
auto it=queue.end();it--;
cout<<(*it).num<<' ';
auto it_2=queue.begin();
cout<<(*it_2).num<<endl;
queue.erase(it);queue.erase(it_2);
}
system("pause");
return 0;
}
H:编程填空:数据库内的学生信息
描述
程序填空,使得下面的程序,先输出
(Tom,80),(Tom,70),(Jone,90),(Jack,70),(Alice,100),
(Tom,78),(Tom,78),(Jone,90),(Jack,70),(Alice,100),
(70,Jack),(70,Tom),(80,Tom),(90,Jone),(100,Alice),
(70,Error),(70,Error),(80,Tom),(90,Jone),(100,Alice),
******
然后,再根据输入数据按要求产生输出数据
#include <iostream>
#include <string>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;
// 在此处补充你的代码
struct Student
{
string name;
int score;
};
template <class T>
void Print(T first,T last) {
for(;first!= last; ++ first)
cout << * first << ",";
cout << endl;
}
int main()
{
Student s[] = { {"Tom",80},{"Jack",70},
{"Jone",90},{"Tom",70},{"Alice",100} };
MyMultimap<string,int> mp;
for(int i = 0; i<5; ++ i)
mp.insert(make_pair(s[i].name,s[i].score));
Print(mp.begin(),mp.end()); //按姓名从大到小输出
mp.Set("Tom",78); //把所有名为"Tom"的学生的成绩都设置为78
Print(mp.begin(),mp.end());
MyMultimap<int,string,less<int> > mp2;
for(int i = 0; i<5; ++ i)
mp2.insert(make_pair(s[i].score,s[i].name));
Print(mp2.begin(),mp2.end()); //按成绩从小到大输出
mp2.Set(70,"Error"); //把所有成绩为70的学生,名字都改为"Error"
Print(mp2.begin(),mp2.end());
cout << "******" << endl;
mp.clear();
string name;
string cmd;
int score;
while(cin >> cmd ) {
if( cmd == "A") {
cin >> name >> score;
if(mp.find(name) != mp.end() ) {
cout << "erroe" << endl;
}
mp.insert(make_pair(name,score));
}
else if(cmd == "Q") {
cin >> name;
MyMultimap<string,int>::iterator p = mp.find(name);
if( p!= mp.end()) {
cout << p->second << endl;
}
else {
cout << "Not Found" << endl;
}
}
}
return 0;
}
输入
输入数据的每一行,格式为以下之一:
A name score
Q name score
name是个不带个空格的字符串,长度小于 20
score是个整数,能用int表示
A name score 表示往数据库中新增一个姓名为name的学生,其分数为score。开始时数据库中一个学生也没有。
Q name 表示在数据库中查询姓名为name的学生的分数
数据保证学生不重名。
输入数据少于200,000行。
输出
对于每个查询,输出学生的分数。如果查不到,则输出 "Not Found"
样例输入
A Tom1 30
A Tom2 40
Q Tom3
A Tom4 89
Q Tom1
Q Tom2
样例输出
(Tom,80),(Tom,70),(Jone,90),(Jack,70),(Alice,100),
(Tom,78),(Tom,78),(Jone,90),(Jack,70),(Alice,100),
(70,Jack),(70,Tom),(80,Tom),(90,Jone),(100,Alice),
(70,Error),(70,Error),(80,Tom),(90,Jone),(100,Alice),
******
Not Found
30
40
提示
-
编写模板的时候,连续的两个 “>”最好要用空格分开,以免被编译器看作是 ">>"运算符。VS可能无此问题,但是Dev C++和服务器上的编译环境会有这个问题。
比如 vector<vector> 有可能出错,要改成 vector<vector > -
在模板中写迭代器时,最好在前面加上 typename关键字,否则可能会编译错。VS可能无此问题,但是Dev C++和服务器上的编译环境会有这个问题。
Solution
我们通过报错可以发现,这题需要我们定义一个模板类了,但是,对于pred(谓词,返回一个bool型变量),前面是有缺省的,所以我们需要一个greater来顶一下
剩下的其实要说的不多,还有就是,这个public的第一行是因为,下面代码中的iterator类缺少了定义,我们需要把它称作一个新的名字
然后,这个输出函数要写在外面,因为输出的应该是对于外部函数而言的,而不是类变量
#include <iostream>
#include <string>
#include <map>
#include <iterator>
#include <algorithm>
using namespace std;
template<class T1,class T2,class Pred=greater<T1>>
class MyMultimap{
private:
multimap<T1,T2,Pred>ma;
public:
typedef typename multimap<T1,T2,Pred>::iterator iterator;
MyMultimap(){
ma.clear();
}
void insert(pair<T1,T2>x){
ma.insert(x);
}
auto begin(){
return ma.begin();
}
auto end(){
return ma.end();
}
void Set(T1 x,T2 y){
for(auto it=ma.begin();it!=ma.end();it++){
if(it->first==x) it->second=y;
}
}
void clear(){
ma.clear();
}
auto find(T1 x){
return ma.find(x);
}
};
template<class T1,class T2>
ostream &operator<<(ostream &os,const pair<T1,T2>x){
os<<'('<<x.first<<','<<x.second<<')';
return os;
}
struct Student
{
string name;
int score;
};
template <class T>
void Print(T first,T last) {
for(;first!= last; ++ first)
cout << * first << ",";
cout << endl;
}
int main()
{
Student s[] = { {"Tom",80},{"Jack",70},
{"Jone",90},{"Tom",70},{"Alice",100} };
MyMultimap<string,int> mp;
for(int i = 0; i<5; ++ i)
mp.insert(make_pair(s[i].name,s[i].score));
Print(mp.begin(),mp.end()); //按姓名从大到小输出
mp.Set("Tom",78); //把所有名为"Tom"的学生的成绩都设置为78
Print(mp.begin(),mp.end());
MyMultimap<int,string,less<int> > mp2;
for(int i = 0; i<5; ++ i)
mp2.insert(make_pair(s[i].score,s[i].name));
Print(mp2.begin(),mp2.end()); //按成绩从小到大输出
mp2.Set(70,"Error"); //把所有成绩为70的学生,名字都改为"Error"
Print(mp2.begin(),mp2.end());
cout << "******" << endl;
mp.clear();
string name;
string cmd;
int score;
while(cin >> cmd ) {
if( cmd == "A") {
cin >> name >> score;
if(mp.find(name) != mp.end() ) {
cout << "erroe" << endl;
}
mp.insert(make_pair(name,score));
}
else if(cmd == "Q") {
cin >> name;
MyMultimap<string,int>::iterator p = mp.find(name);
if( p!= mp.end()) {
cout << p->second << endl;
}
else {
cout << "Not Found" << endl;
}
}
}
return 0;
}
今天手好酸ovo
后半学期,也请各位继续关注:
《我的青春线代物语果然有问题》
《高数女主养成计划》
《程设の旅》
《青春猪头少年不会梦到多智能体吃豆人》
《某Linux的开源软件》
还有——
《我的算法竞赛不可能这么可爱》
本期到此结束!

浙公网安备 33010602011771号