C++的STL总结笔记:STL总结笔记(实用 / 比赛)


文章目录

  • 1 vector
    • 模板
    • 1039(25:学生-课程表)
    • 1047(25:学生-课程表)
  • 2 set
    • 模板
    • 1063(25:求两个set的并集(去重)、交集(去重))
    • 1120(20:N个数,每个数的各位求和,输出相同的和(去重))
    • 1129(25:set排序)
  • 3 map
    • 模板
    • 1022(30:数字图书馆,查询)【非满分】
    • 1054(20:hash,用map)
    • 1071(25:提取单词)
  • 4 stack
  • 5 queue

1 vector

模板

常用定义:

vector<int> vect;
vector<int> vects[N]; // N个vector
//vector<int> vects(N);   // N个int

1039(25:学生-课程表)

(1)题目
学生-课程表

(2)代码

#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>using namespace std;const int N_stu = 40000+10;
const int N_cour = 2500+10;const int maxn = 26*26*26*10 +10;vector<int> stus[maxn];   //stus[i]:id=i的学生的所有课程int hashTable(char str[]){int id=0;for(int i=0; i<3; i++){id = id*26 + str[i]-'A';}id = id*10 + str[3]-'0';return id;
}int main(){int n,k;scanf("%d%d", &n, &k);int index, num;char name[10];int id;for(int i=0; i<k; i++){scanf("%d%d", &index, &num);for(int j=0; j<num; j++){scanf("%s", name);id = hashTable(name);stus[id].push_back(index);}}for(int i=0; i<n; i++){scanf("%s", name);id = hashTable(name);sort(stus[id].begin(),stus[id].end());printf("%s %d", name, stus[id].size());for(int j=0; j<stus[id].size(); j++){printf(" %d", stus[id][j]);}printf("\n");}return 0;
}

(3)小结

  • 学生名:3个大写字母+1个数字
    用hash存储,将字符串转换为唯一的数
  • 如何设计vector类型的变量(stu[maxn]),根据输出

1047(25:学生-课程表)

(1)题目
学生-课程表(比较A1039)

(2)代码

#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
#include<string>using namespace std;const int N=40000+10;
const int K=2500+10;vector<string> vect[K];    // vect[i]: 课程i的所有学生int main(){int n, k;scanf("%d%d", &n, &k);char name[10];int num;string s;int c;for(int i=0; i<n; i++){scanf("%s%d", name, &num);s = name;for(int j=0; j<num; j++){scanf("%d",&c);vect[c].push_back(s);}}for(int i=1; i<=k; i++){printf("%d %d\n", i, vect[i].size());sort(vect[i].begin(), vect[i].end());for(int j=0; j<vect[i].size(); j++){printf("%s\n", vect[i][j].c_str());}}return 0;
}

(3)小结

  • vector存字符串数组:vector<string>,最好用string
  • 中途用到string类型,但又不想cin和scanf混用
    则: 输入char[]变量,转换为string类型
    char name[10];
    scanf(“%s”, name);
    string str;
    str = name; //char[]变为string

2 set

模板

常用定义:

set<int> st;
vector<set<int> > vects(N);     //N个set,(N)用小括号!!!//排序
set<int, greater<int> > st; //降序
set<int, cmp> st; // cmp自定义

1063(25:求两个set的并集(去重)、交集(去重))

(1)题目

求两个set的并集(去重)、交集(去重)

(2)代码

#include<cstdio>
#include<set>
#include<vector>using namespace std;const int N=100;vector<set<int> > vects(N);  // N个set,用小括号double simi(int index1, int index2){int nc=0,nt=0;set<int>::iterator it = vects[index1].begin();// nt = set2的大小// 遍历set1:对于*it, 如果set2中存在,则nc++,否则nt++nt = vects[index2].size();for(; it!=vects[index1].end(); it++){if(vects[index2].find(*it) == vects[index2].end()){     //查找失败nt++;   //set2中没有set1中有的元素(set1-set2)}else{nc++;}}double r = ((double)nc/nt) *100;return r;
}int main()
{int n;scanf("%d", &n);for(int i=1; i<=n; i++){int m;scanf("%d", &m);for(int j=0; j<m; j++){int t;scanf("%d", &t);vects[i].insert(t);}}int k;scanf("%d", &k);for(int i=0; i<k; i++){int index1, index2;double r;scanf("%d%d", &index1, &index2);r = simi(index1, index2);printf("%.1f%%\n", r);}return 0;
}

(3)小结

  • 用auto定义it(只能在C++11中)
    auto it = vects.begin();
  • 求交集、并集、差集
    遍历set1:
    对于set1中元素 x ,判断set2中有没有(set.find(x))
  • 输出结果为 %
    double r = … *100;
    printf("%.2f %% ", r); //80.20%

1120(20:N个数,每个数的各位求和,输出相同的和(去重))

(1)题目

N个数,每个数的各位求和,输出相同的和(去重)

(2)代码

#include<cstdio>
#include<set>using namespace std;set<int> st;int friend_sum(int num){int sum=0;while(num!=0){sum += num%10;num /= 10;}return sum;
}int main()
{//freopen("in.txt", "r", stdin);int n;scanf("%d", &n);for(int i=0; i<n; i++){int t;scanf("%d", &t);int sum;sum = friend_sum(t);st.insert(sum);}set<int>::iterator it = st.begin();printf("%d\n", st.size());for(; it!=st.end(); it++){if(it!=st.begin()){printf(" ");}printf("%d",*it);}//fclose(stdin);return 0;
}

(3)小结

  • 对于一个正整数n,得到各位上的数字【从个位开始】
 int  a[100];    //存储每一位【a[0]:个位】int i=0;while(n!=0){a[i] = n%10;n /= 10;i++;
}
  • 当题目没有明确N的大小:
    可能只需要for循环,不需要创建存储空间
    可能用vector存储
  • a[n]的输出格式(没有多余空格)
    a[1]空格a[2]空格a[3]
for(int i=0; i<n; i++){if(i!=0){printf(" ");}printf("%d",*it);
}

1129(25:set排序)

(1)题目
set排序

(2)代码


#include<cstdio>
#include<set>using namespace std;const int N = 50000+10;typedef struct{int data;int freq;   //访问次数
}Node;// freq[]降序,再set<int>升序
struct cmp{bool operator()(const Node &node1, const Node &node2){if(node1.freq==node2.freq){return node1.data < node2.data;}else{return node1.freq > node2.freq;}}
};
set<Node,cmp> st;    //输出rec[]不重复int freq[N];int main()
{//freopen("in.txt", "r", stdin);int n,k;scanf("%d%d", &n, &k);for(int i=0; i<n; i++){int t;scanf("%d", &t);set<Node,cmp>::iterator it;if(i!=0){   //从第二个开始// 输出,取set的前k个printf("%d: ",t);it = st.begin();int j=0;for(; it!=st.end() && j<k; it++,j++){if(it!=st.begin()){printf(" ");}printf("%d",*it);}printf("\n");}it = st.find(Node{t,freq[t]});freq[t]++;if(it!=st.end()){   //查找成功st.erase(it);      //由于set的cmp operator()重载,set中的元素变为const,不能修改,只能删除再插}st.insert(Node{t, freq[t]});}//fclose(stdin);return 0;
}

(3)小结

  • iterator的定义,必须和指向的STL定义 完全相同
    set<int,cmp> st;
    set<int,cmp>::iterator it = st.begin();

  • 排序:STL+sort()、set+内部、prior_queue+内部
    多于一次排序(当…相等,再比较…时)时:必须使STL容器存储结构体struct才不会出错
    如:以下情况set会出错(freq[]和set<int>中元素分开)

int freq[N];    //访问次数struct cmp{    // freq[]降序,再set<int>升序bool operator()(const int &a, const int &b){if(freq[a]==freq[b]){return a < b;}else{return freq[a] > freq[b];}}
};
set<int,cmp> st;

以下情况不会出错

typedef struct{int data;int freq;   //访问次数
}Node;// freq[]降序,再set<int>升序
struct cmp{bool operator()(const Node &node1, const Node &node2){if(node1.freq==node2.freq){return node1.data < node2.data;}else{return node1.freq > node2.freq;}}
};
set<Node,cmp> st;
  • 排序:set+内部、prior_queue+内部 重载operator()会使 元素变为const,不可再修改
    如:Node结构体的元素的值不可再修改,只能删除再插入新的Node
struct cmp{bool operator()(const Node &node1, const Node &node2){if(node1.freq==node2.freq){return node1.data < node2.data;}else{return node1.freq > node2.freq;}}
};
set<Node,cmp> st;
  • set只输出前k项
it = st.begin();
int j=0;
for(; it!=st.end() && j<k; it++,j++){...
}

3 map

模板

查询:map<key, value> mp; value可以为多个
常用定义:

map<string, set<int> > mp;   //value多个,有序且唯一,设为set

1022(30:数字图书馆,查询)【非满分】

(1)题目
数字图书馆:查询

(2)代码

#include<cstdio>
#include<string>
#include<iostream>
#include<map>
#include<set>using namespace std;map<string, set<int> > title, author, keyWords, publisher, year;// 参数为STL,都用引用,快些
void query(map<string, set<int> > &mp, string &str){map<string, set<int> >::iterator it1;it1 = mp.find(str);if(it1!=mp.end()){  //查找成功set<int>::iterator it2 = mp[str].begin();for(; it2!=mp[str].end(); it2++){printf("%d\n",*it2);}}else{printf("Not Found\n");  //失败}
}int main(){//freopen("in.txt", "r", stdin);int n;cin>>n;for(int i=0; i<n; i++){int id;cin>>id;string str;cin.ignore();       // cin>>id后会有个'\n',getline(cin, str);title[str].insert(id);getline(cin, str);author[str].insert(id);// key words没有明确输入几个while(cin>>str){keyWords[str].insert(id);char ch = getchar();    //为空格 或 \nif(ch=='\n') break;}getline(cin, str);publisher[str].insert(id);getline(cin, str);year[str].insert(id);}int m;cin>>m;for(int i=0; i<m; i++){int num;scanf("%d: ",&num);string str;getline(cin, str);printf("%d: %s\n",num,str.c_str());switch(num){case 1:query(title, str);break;case 2:query(author, str);break;case 3:query(keyWords, str);break;case 4:query(publisher, str);break;case 5:query(year, str);break;default:break;}}//fclose(stdin);return 0;
}

(3)小结

  • 没有明确输入几个(一行输入,空格分开)
while(cin>>...){...char ch = getchar();    //为空格 或 \nif(ch=='\n') break;}或while(scanf(...)){...char ch = getchar();    //为空格 或 \nif(ch=='\n') break;}
  • 当超时时,将自己写的函数的参数改为 引用
    特别:函数的参数为:STL时(string、vector、map等)
  • 当所有数据都显示 超时时, 可能没删freopen
  • cin / scanf 后接 gets / getline 会多读一个空格或只读\n,必须加cin.ignore()
 int n;string str;scanf("%d", &n);// 必须先忽略一个字符cin.ignore();//getline(cin, str);printf("n:%d\n",n);printf("s:%s\n", str.c_str());

1054(20:hash,用map)

(1)题目
hash:用map

(2)代码

#include<cstdio>
#include<map>using namespace std;int main(){//freopen("in.txt", "r", stdin);int m,n;scanf("%d%d", &m, &n);map<int, int> mp;       // 默认=0for(int i=0; i<n; i++){for(int j=0; j<m; j++){int t;scanf("%d", &t);mp[t]++;}}map<int , int>::iterator it;for(it=mp.begin(); it!=mp.end(); it++){if(it->second > (m*n/2)){printf("%d\n", it->first);break;}}//fclose(stdin);return 0;
}

(3)小结

  • hash:直接定址,当MAXN较大时,不能用数组,如下
    int arr[MAXN];
    最好用map
    map<int, int> mp;

1071(25:提取单词)

(1)题目
提取单词

(2)代码

#include<cstdio>
#include<string>
#include<iostream>
#include<map>
#include<cctype>using namespace std;string str, word="";int main(){//freopen("in.txt", "r", stdin);getline(cin,str);map<string, int> mp;for(int i=0; i<str.length(); i++){char ch = str[i];if(isalnum(str[i])){str[i] = tolower(str[i]);word += str[i];if(i==str.length()-1){        //易漏,当最后一个是字母结尾,map容易漏最后一个wordmp[word] ++;}}else{if(word!=""){mp[word] ++;}            word = "";}      }int max0 = 0;map<string, int>::iterator it, it_max;for(it=mp.begin(); it!=mp.end(); it++){if(it->second > max0){      //max0相同,按字典序的第一个(map按key)it_max = it;max0 = it->second;}}printf("%s %d\n",it_max->first.c_str(), it_max->second);//fclose(stdin);return 0;
}

(3)小结

  • 灵活用头文件<cctype>

    判断一个字符是否为 [0-9 A-Z a-z],bool isalnum(ch)

#include<cctype>char ch;
if(isalnum(ch)){...}
  • map的key有序:ascII,从小到大
  • 段错误:
    数组太小
    数组越界
    也可能答案错误(有情况没考虑到)

4 stack

5 queue

PAT之STL:vector、set、map、stack、queue相关推荐

  1. programming review (c++): (1)vector, linked list, stack, queue, map, string, bit manipulation

    编程题常用知识点的review. most important: 想好(1)详尽步骤(2)边界特例,再开始写代码. I.vector #include <iostream> //0.头文件 ...

  2. Stack/Queue与Vector/List的联系

    Vector:(顺序表[数组存储]) 1.当申请的空间不足的时候,需要再次开辟一块更大的空间,并把值拷过去. 2.对于尾删和尾插是比较方便的,只需要改动最后一个元素即可.不会改动原有的空间.适用于多次 ...

  3. MFC中STL容器中Vector,List,Map基本用法汇总

    容器就是数据结构的泛指,迭代器就是指针的泛指,可以指向元素.它可以用来存储数据,就比如杯子用来装水一样.而STL中的容器有很多,它包括vector,list,map,deque,set等.我就简单列举 ...

  4. 使gdb支持string、vector、map等STL类型数据的查看(linux)

    前提条件 (1)需要安装python [danni@vm-xxx-18 develop]$ python --version Python 2.6.6 (2)需要有gcc [danni@vm-xxx- ...

  5. 【STL详解】stack

    文章目录 前言 一.STL? 二.stack 1. stack的创建 2. stack相关方法 3. 如何对satck进行排序 前言 本篇文章将总结SLT - stack,以及其常用方法. 一.STL ...

  6. Java集合List,Set,Map,Queue,Deque

    集合是Java基础中非常重要的一部分,Java提供了非常丰富的集合API,了解各个集合的特点,怎么样在各种各样的场景中使用正确的集合,非常重要,也是一个Java程序员最基本的素养. 整体了解 Java ...

  7. 数据结构与算法笔记:贪心策略之BSTBBST, Hashtable+Dictionary+Map, Priority Queue~Heap, Minium Spanning Tree

    BST & BBST BST(Binary Search Tree) 二叉搜索树,也就是使用二叉树来做查找 BBST(Balanced Binary Search Tree) 平衡二叉搜索树 ...

  8. c++STL容器的Map和multimap

    STL容器的Map和multimap map/multimap的简介 map/multimap对象的默认构造 map的插入与迭代器 迭代器遍历 map对象的拷贝构造与赋值 map的大小 map的删除 ...

  9. STL vector的erase操作问题

    STL vector的erase操作问题 一老大说CSDN上有篇博文("关于STL vector的erase操作",地址是:http://blog.csdn.net/tingya/ ...

  10. 【PAT乙】1085 PAT单位排行 (25分) map排序

    problem 每次 PAT 考试结束后,考试中心都会发布一个考生单位排行榜.本题就请你实现这个功能. 输入格式: 输入第一行给出一个正整数 N(≤10 ​5 ​​ ),即考生人数.随后 N 行,每行 ...

最新文章

  1. MySQL注入中报错的利用
  2. 我的机器学习入门之路(中)——深度学习(自然语言处理)
  3. 一个类型初始值设定项引发异常
  4. 【Selenium 爬爬 猪 八 戒】
  5. Python 爬虫---(6) beautifulSoup 库的使用
  6. 算法不会,尚能饭否之对分查找二叉树(又为快速排序之二叉树实现)
  7. webbrowser只对浏览器外应用程序以及在_常用浏览器大盘点!
  8. java迷宫算法继承_求Java关于迷宫的算法(用栈实现)
  9. 【Android】OKHTTP使用
  10. 考上研究生就脱单?快来看看这些女生多的大学!
  11. 广联达登录显示服务器异常求回答,求助【服务器异常】
  12. 资深工程师PCB经验介绍
  13. excel数据库_标签打印软件中Excel数据整理及导入
  14. Day.js 一个轻量级的 JavaScript 时间日期处理库
  15. linux最上层目录是什么,Linux基础知识之--目录组成结构,当前目录及上层目录表示方法,目录访问权限...
  16. windows路由表完全掌握(内容:路由表解析,读懂路由表)
  17. Java读取MARC元数据 代码
  18. Docker部署及常见问题
  19. 团队作业-Beta版本发布
  20. Python导入第三方库以及报错 Error..........处理办法

热门文章

  1. 手把手教你逆向分析 Android 程序
  2. SSH项目ueditor插件jsp版本
  3. Using Java in Debian
  4. 日志系统实战(一)—AOP静态注入
  5. 什么程序员最易找工作? 十大热门语言大汇集
  6. java中如何获得屏幕的宽度和高度,android-如何获取屏幕的宽度和高度
  7. Java Mail 相关资料
  8. java 财付通支付_微信微信支付已拿下51%的份额,远超支付宝的41%
  9. python连接池 commit,连接池请求Python
  10. elementui的横向滚动_记一次element-ui配置化table组件的适应性问题(横向滚动条)...