ACM常用的C++ && STL

内容

  1. c++输入输出
  2. c++ string
  3. vector:不定长数组
  4. map:映射
  5. queue:队列
  6. sort:排序
  7. priority_queue:优先队列

c++输入输出

 1 #include <iostream>    //c++输入输出的头文件
 2 using namespace std;   //名称空间, 不懂死记硬背
 3 
 4 int main(){
 5     int a;  //或是long long a; double a; char a[10]; 等等,总之不需要像c语言一样要占位符
 6     cin >> a;  //输入
 7     cout << a; //输出
 8 
 9     cout << "abcdefg";  //输出字符串
10     cout << endl; //换行
11     cout << "abcdefg" << endl; //合并cout,效果和上面两个语句一样
12 
13     int b;
14     cin >> a >> b;  //合并cin,效果和 cin >> a;  cin >> b; 一样
15     cout << "abcdefg\n"; //效果和上一个语句一样
16     cout << 'a'; //输出字母a,而不是ASCII码,这个和c语言有点不一样
17     
18     return 0;
19 }

在这里我们可以看到,用c++输入输出能够极大方面减少错误率,而且支持的对象也非常多(把上面的int a改成double a / long long a等等都是可以的),c语言的输入输出实在是有点麻烦。不过c语言的输入输出优点也是有的:格式化输出 printf(); 更方便,而且效率更高(比c++的输入输出要快)。所以,一般情况可以直接用c++的输入输出,而对于数据输入量大的题目最好改成c语言的输入输出。另外,如果想在c++中用c的头文件,只需要把 #include <xxx.h> 改成 #include <cxxx> 。举个例子,c语言中的输入输出头文件是 #include <stdio.h>,那么在c++中就是 #include <cstdio>。

c++ string

string类:这个就是升级版的 char s[] 。顾名思义,就是字符串,但是这个字符串比 char s[] 方便很多。我们先来看看string的头文件和名称空间:

1 #include <string>
2 using namespace std;

是不是又看到了 using namespace std; ,这个几乎是每个头文件的通用名称空间,其他的c++头文件默认也是这个名称空间,而且还可以这样写:

1 #include <iostream>
2 #include <string>
3 using namespace std;

以后写完一堆头文件后直接在末尾加一句 using namespace std; 就行了。

string的用法:

 1 #include <iostream>    
 2 #include <cstdio>
 3 #include <string>
 4 using namespace std;   
 5 
 6 int main(){
 7     string s;
 8     cin >> s; //输入
 9     cout << s; //输出
10 
11     string s2;
12     s2 = s;   //把s里面的内容复制到s2里面
13 
14     string s3;
15     s3 = s + s2; //拼接s和s2然后复制到s3里面
16     s = s + s2; //把s2拼接到s末尾
17 
18     int len = s.length(); //计算s的长度, 然后赋值到len,功能和strlen()一样,都不算'\0'
19 
20     if(s[0] != 'a') s[0] = 'a'; //可以直接像char s[]一样访问和修改
21 
22     int cnt = 0;
23     if(s == s2) cnt++;  //可以直接比较s和s2是否相等
24 
25     return 0;
26 }

vector:不定长数组

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <vector>     //相关头文件
 4 using namespace std;
 5 
 6 int main(){
 7     //vector(不定长数组)用法介绍
 8     vector<int> G;     //创建vector
 9     G.push_back(5);    //加入元素5, 类似于栈
10     G.push_back(3);    //加入元素3
11     G.push_back(7);    //加入元素7
12     //这时vector里面有元素: 5, 3, 7
13 
14     //访问
15     int a;
16     a = G[0];   //a被赋值为vector里面的第一个元素,即a = 5
17     a = G[1];   //a被赋值为vector里面的第二个元素,即a = 3
18 
19     //获得vector的大小: G.size()    //这里是遍历vector里面的元素
20     for(int i = 0; i < G.size(); i++){
21         printf("%d\n", G[i]);
22         //这里G.size() == 3, 所以输出G[0], G[1], G[2]
23     }
24     printf("\n");
25 
26     G.clear(); //清空不定长数组G, 相当于不定长数组大小设为0
27 
28     //高级用法: vector数组
29     vector<int> g[3];
30     //这里创建了3个vector, 其中分别是g[0], g[1], g[2]
31     g[1].push_back(4);   //向g[1]这个vector加入元素4
32     g[1].push_back(1);   //向g[1]这个vector加入元素1
33 
34     //访问
35     a = g[1][0];   //a被赋值为g[1]里面的第一个元素,即a = 4
36     a = g[1][1];   //a被赋值为g[1]里面的第二个元素,即a = 1
37 
38     for(int i = 0; i < g[1].size(); i++){
39         printf("%d\n", g[1][i]);
40         //这里g[1].size() == 2, 所以输出g[1][0], g[1][1]
41     }
42 
43     return 0;
44 }

map:映射

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <map>
 4 #include <string>
 5 using namespace std;
 6 
 7 int main(){
 8     //map用法介绍
 9     map<string, int> mp;     //创建一个map: 从string到1的映射
10     mp["abc"] = 1;   //建立从字符串"abc"到整数1的映射
11     string s = "efg";   //创建一个string
12     mp[s] = 5;       //建立从字符串"efg"到整数5的映射
13 
14     //访问
15     int a;
16     a = mp["abc"];    //这时mp["abc"]的值为1, 也就是a = 1
17     cout << a << endl;
18     a = mp[s];        //这时mp[s]的值为5, 也就是a = 5
19     cout << a << endl;
20 
21     //使用char数组
22     char s2[5] = "gsd";
23     mp[s2] = 9;       //建立从字符串"gsd"到整数9的映射
24     cout << mp[s2] << endl;
25 
26     mp.clear();  //清空mp里面的元素, 相当于把所有映射都抹去
27 
28     //最后注意的是, 虽然map看起来很像hash, 但其内部实现不是hash, 而是一颗树(红黑树)
29     //也就是说, 当进行访问map的操作时, 时间复杂度为O(log m)(m为映射数量), 并不是O(1)
30 
31     return 0;
32 }

 

queue:队列

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <queue>
 4 using namespace std;
 5 
 6 int main(){
 7     //queue基本用法
 8     queue<int> q;    //创建一个先进先出的队列(也就是这个队列只能在尾部加入元素, 头部取出元素, 这个是关键)
 9     q.push(1);    //加入元素1
10     q.push(2);    //加入元素2
11     q.push(3);    //加入元素3
12     //这时队列是: 1, 2, 3
13 
14     //访问
15     int a;
16     a = q.front();  //这时q.front()的值为1, 所以a = 1, 注意这里只是读取队列首元素, 并没有弹出元素
17     cout << a << endl;
18     a = q.front();
19     cout << a << endl;
20 
21     //弹出
22     q.pop();    //弹出队列的首元素, 也就是变成2, 3
23     a = q.front();
24     cout << a << endl;
25 
26     //判断队列是否为空
27     q.pop();    //弹出队列的首元素, 也就是变成3
28     q.pop();    //弹出队列的首元素, 此时队列为空
29     if(q.empty()) cout << "Yes\n";      //如果队列为空, 则q.empty()为真, 则输出"Yes"
30     if(q.size() == 0) cout << "Yes\n";  //如果队列大小为0, 则输出"Yes"
31 
32     return 0;
33 }

sort:排序

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm>
 4 using namespace std;
 5 //先从主函数看
 6 
 7 struct node{
 8     int first, second;
 9 };
10 
11 bool cmp1(int x, int y){
12     return x > y;    //从大到小排
13 }
14 
15 bool cmp2(int x, int y){
16     return x < y;    //从小到大排
17 }
18 
19 bool cmp_node(node x, node y){
20     if(x.first == y.first) return x.second < y.second;
21     else return x.first < y.first;
22     //这里的意思: 优先对结构体的第一个值进行排序, 如果第一个值相等, 就按照第二个值进行排序
23 }
24 
25 int main(){
26     //sort的用法
27     int a[5] = {5,4,3,2,1};
28     sort(a, a+5);    //默认对数组a进行从小到大排序
29     for(int i = 0; i < 5; i++){
30         cout << a[i] << " ";
31     }
32     cout << endl;
33 
34     string s[3] = {"bcd", "abc", "a"};
35     sort(s, s+3);    //默认对字符串进行字典序排序
36     for(int i = 0; i < 3; i++){
37         cout << s[i] << endl;
38     }
39     cout << endl;
40 
41     //自定义比较级(比较函数):
42     sort(a, a+5, cmp1);  //按cmp1的比较级排序, 注意这里cmp1后面不能加()
43     for(int i = 0; i < 5; i++){
44         cout << a[i] << " ";
45     }
46     cout << endl;
47 
48     sort(a, a+5, cmp2);   //按cmp2的比较级排序
49     for(int i = 0; i < 5; i++){
50         cout << a[i] << " ";
51     }
52     cout << endl;
53 
54     cout << endl;
55     //对结构体进行排序
56     node G[3] = {{5,3}, {5, 2}, {1, 9}};
57     sort(G, G+3, cmp_node);   //按照cmp_node进行排序
58     for(int i = 0; i < 3; i++){
59         printf("G[%d]: %d %d\n", i, G[i].first, G[i].second);
60     }
61     cout << endl;
62 
63     return 0;
64 }

priority_queue:优先队列

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <queue>
 4 #include <vector>
 5 using namespace std;
 6 //从主函数看起
 7 
 8 struct node{
 9     int first, second;
10 };
11 
12 struct cmp1{    //这里比较级是用结构体, 而不是函数
13     bool operator () (int a, int b){   //重载操作, 记住就行
14         return a > b;   
15         //小的优先在前面, 因为是用"堆"去实现的, 不清楚堆就直接记住和sort的cmp刚好相反
16     }
17 };
18 
19 struct cmp2{
20     bool operator () (node a, node b){
21         if(a.first == b.first) return b.second > b.second;
22         return a.first > b.first;
23     }
24 };
25 
26 int main(){
27     //priority_queue基本用法
28     priority_queue<int> q;  //创建一个优先队列
29     q.push(1);    //加入元素1
30     q.push(3);    //加入元素3
31     q.push(2);    //加入元素2
32     
33     if(!q.empty()) printf("YES\n");    //q.empty():判断优先队列是否为空
34     
35     int a;
36     while(!q.empty()){
37         a = q.top();    //这里只是读取队列首元素, 并没有弹出元素
38         printf("%d ", a);
39         q.pop();        //弹出首元素
40     }
41     printf("\n");
42     //运行上面程序,发现输出为:3, 2, 1, 也就是说, 默认优先队列默认从大到小排列
43     
44     priority_queue<int, vector<int>, less<int> > q_less;
45     //创建一个优先级为:从大到小, 排的优先队列
46     
47     priority_queue<int, vector<int>, greater<int> > q_great;
48     //创建一个优先级为:从小到大, 排的优先队列
49     
50     priority_queue<int, vector<int>, cmp1> q_cmp1;
51     //自定义比较级:cmp1
52     
53     priority_queue<node, vector<node>, cmp1> q_cmp1;
54     //自定义比较级:cmp2
55     return 0;
56 }

 

posted @ 2019-06-10 21:00  MrEdge  阅读(2023)  评论(0编辑  收藏  举报