C++ Intro & STL
Presented By Du
Outline
- deque
- set and map
- opeartor overloading
- priority queue
- c++ 基本介紹
- string
- vector
- stack and queue
C++ intro
#include <iostream>
using namespace std;
int main()
{
int a;
cin >> a;
cout << a << endl;
}
std::
- std:: 是個名稱空間標示符
- 使用標準函式庫中的函式或物件(cin, cout)都要使用std來限定。
- 這樣編譯器就會明白我們呼叫的cout是名字空間std中的cout。
#include <iostream>
int main()
{
int a;
std :: cin >> a;
std :: cout << a << std::endl;
}
namespace
- 一開始,就宣告使用std的命名空間
- 名稱不能跟關鍵字一樣 EX. int, break(會變色的都算)
#include <bits/stdc++.h>
using namespace std;
namespace first {
int cin = 5;
int break = 10;
// error: expected unqualified-id before 'break'
}
int main()
{
cout << first::cin;
// output : 5;
}
library
#include <iostream>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
using namespace std;
int main()
{
int a;
cin >> a;
cout << a ;
}
萬能標頭檔 ! ! !
#include <bits/stdc++.h>
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a;
cin >> a;
cout << a ;
}
加速器
- ios::sync_with_stdio(false);
- cin和cout要與stdio同步,中間會有一個緩衝,所以導致cin,cout語句輸入輸出緩慢
- cin、cout、endl速度比scanf、printf、\n慢
EOF
#include <bits/stdc++.h>
using namespace std;
int main()
{
int a;
while(cin >> a){
cout << a ;
}
}
String
判斷是否為11的倍數。

string
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
cin >> str;
cout << str << endl;
for(int i = 0; i < str.size(); i++){
cout << str[i] << endl;
}
}
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(cin >> str){
if(str == "0")
break;
int odd = 0, even = 0;
for(int i = 0; i < str.size(); i++){
if(i % 2 != 0){
odd += (str[i] - '0');
}
else even += (str[i] - '0');
}
int ans;
ans = abs(odd - even);
if(ans % 11 != 0)
cout << str << " is" << " not a multiple of 11." << endl;
else
cout << str << " is" << " a multiple of 11." << endl;
}
}
Lab 2
第一個"換成‵‵,第二個"換成’'。
UVA - 272

getline
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
getline(cin, str);
cout << str;
}
#include<bits/stdc++.h>
using namespace std;
int main(){
string str;
int fg = 0;
bool space = false;
while( getline(cin,str) ){
if(space){
cout<<endl;
}
space = true;
for(int i = 0;i < str.size();i++){
if(str[i] == '"'){
if(fg % 2 == 0){
cout << "``";
fg++;
continue;
}
else{
cout << "''";
fg++;
continue;
}
}
else{
cout << str[i];
}
}
}
}
UVA - 272
string 加法
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str1 = "123";
string str2 = "456";
str1 += str2;
cout << str1;
// str1 : 123456
}
stringstream
- 型態轉換的橋樑
#include<bits/stdc++.h>
using namespace std;
int main()
{
stringstream s1;
double b = 0.5;
string str;
s1 << b;
s1 >> str;
cout << str << endl;
}
型態轉換
- int to string : to_string()
- string to int : stoi()
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a = 25;
string str = to_string(a);
cout << str << endl;
int b;
b = stoi(str);
cout << b << endl;
}
Sort

找回文
#include<bits/stdc++.h>
using namespace std;
bool cmp(int a,int b){
return a > b;
}
int main()
{
int arr[] = {4, 5, 8, 3, 7, 1, 2, 6, 10, 9};
sort(arr, arr+10); //由小到大
for(int i=0;i<10;i++){
cout<<arr[i]<<' ';
}
// 1 2 3 4 5 6 7 8 9 10
cout<<endl;
vector<int> v;
for(int i=10;i>0;i--){
v.push_back(i);
}
//10 9 8 7 6 5 4 3 2 1
sort(v.begin(), v.end()); //小到大
for(int i=0;i<v.size();i++){
cout<<v[i]<<' ';
}
// 1 2 3 4 5 6 7 8 9 10
cout<<endl;
string str = "abcd123+-*/";
sort(str.begin(), str.end());
cout<<str<<endl;
//*+-/123abcd
sort(v.begin(), v.end(), cmp);
for(int i=0;i<v.size();i++){
cout<<v[i]<<' ';
}
//10 9 8 7 6 5 4 3 2 1
cout<<endl;
}
S
O
R
T
Reverse
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
reverse(a, a+5); // 轉換0~4
for(int i=0;i<10;i++){
cout<<a[i]<<' ';
}
//4 3 2 1 0 5 6 7 8 9
cout<<endl;
vector<int> v;
for(int i=0;i<10;i++){
v.push_back(i);
}
reverse(v.begin(), v.end());
for(int i=0;i<v.size();i++){
cout<<v[i]<<' ';
}
//9 8 7 6 5 4 3 2 1 0
cout<<endl;
string str = "123";
reverse(str.begin(), str.end());
cout<<str<<endl;
//321
}
UVA - 10945
#include<bits/stdc++.h>
using namespace std;
int main()
{
string str;
while(getline(cin,str)){
if(str == "DONE") break;
string str2 = "";
for(int i = 0;i < str.size();i++){
if(isalpha(str[i])){
str2 += tolower(str[i]);
}
}
string str3 = str2;
reverse(str2.begin(), str2.end());
if(str2 == str3)
cout<<"You won't be eaten!"<<endl;
else
cout<<"Uh oh.."<<endl;
}
}
STL
Why STL
- Standard Template Library
- 內建資料結構
- 不用自己手刻
- 可以自己設定想要儲存的資型態
vector
benefit
- 動態陣列,可以隨時改變大小
- 可以做比array多的事
- v.push_back()
- v.pop_back()
- v.size()
- v.insert()
- v.erase()
- v.front()
- v.back()
- v.begin() //回傳iterator
- v.end() //回傳iterator
- v.clear()
- v.empty()
- v.resize(10)
#include<bits/stdc++.h>
using namespace std;
int main()
{
vector<int> v;
v.resize(5);//預留空間給使用者輸入
v[3] = 5;
cout<<v[3];
for(int i = 0; i < 20; i++){
v.push_back(i); //從後放入
}
cout << v.size() << endl; //vector大小
cout<<v.front();//輸出第一個
cout<<v.back();//輸出最後一個
sort(v.begin(), v.end());//由大到小sort
v.insert(v.begin() + 2, 30); // 插入
v.erase(v.begin() + 1); //刪除
v.erase(v.begin() + 1, v.begin() + 3); //刪除某段
for(int i = 0; i < v.size(); i++){
cout << v[i] << " ";
}
while(!v.empty()){
v.pop_back(); //從後丟出
}
v.clear(); //清空
if(v.empty()) cout << "It is empty!!\n"; //是否為空
}
2D vector
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<int>v[10]; // 長度為10的vector array
for(int i = 0; i < 10; i++){
v1[i].resize(5);
v1[i][3] = 3;
}
for(int i = 0; i < 10; i++){
for(int j = 0; j < v1[i].size(); j++){
cout << v1[i][j] << ' ';
}
cout << '\n';
}
// size => 10 x 5
return 0;
}
2D vector
#include <bits/stdc++.h>
using namespace std;
int main(){
vector<vector<int>> v2; // 2D vector
v2.resize(5);
for(int i = 0; i < 5; i++){
v2[i].resize(10);
v2[i][5] = 5;
}
for(int i = 0; i < v2.size(); i++){
for(int j = 0; j < v2[i].size(); j++){
cout << v2[i][j] << ' ';
}
cout << '\n';
}
//vector size = 5 x 10
}
stack
- FILO: First In Last Out
- LIFO: Last In First Out





- s.push()
- s.pop()
- s.top()
- s.empty()
- s.size()
#include <bits/stdc++.h>
using namespace std;
int main(){
stack<int>Stack;
Stack.push(1);
//將東西放在stack的最上方
Stack.push(2);
Stack.push(3);
cout << "the top of the stack is " << Stack.top() << '\n';
//3(回傳stack最上方的值)
Stack.pop();
//將stack最上方的值刪除
cout << "the top of the stack is " << Stack.top() << '\n';
//2(回傳stack最上方的值)
cout << "the size of the stack is " << Stack.size() << '\n';
//2(回傳stack現在有幾個元素)
while(!Stack.empty()){
Stack.pop();
}
//清空stack
}
Lab1 Stack練習
給定兩種操作
push x : 在 stack 插入 x
pop : 刪除 stack 的頂端元素
對於每個 pop 操作,如果 stack 沒有元素,輸出"The stack is empty.",否則請輸出被刪除的元素。

queue
- FIFO: First In First Out
- LILO: Last In Last Out
理論演示 (我就偷懶不想做簡報

- q.push()
- q.pop()
- q.size()
- q.front()
- q.back()
- q.empty()
#include <bits/stdc++.h>
using namespace std;
int main(){
queue<int>Queue;
Queue.push(1);
//將東西放在queue的最後方
Queue.push(2);
Queue.push(3);
cout << "the front of the Queue is " << Queue.front() << '\n';
// 1(回傳最前方的值)
cout << "the back of the Queue is " << Queue.back() << '\n';
// 3(回傳最後方的值)
Queue.pop();
//將queue最前方的值刪除
cout << "the front of the Queue is " << Queue.front() << '\n';
// 2(回傳最前方的值)
cout << "the size of the queue is " << Queue.size() << '\n';
// 2(回傳現在有幾個元素)
while(!Queue.empty()){
Queue.pop();
}
//清空queue
}
queue練習
給定兩種操作 push x : 在 queue 插入 x pop : 刪除 queue 的頂端元素 對於每個 pop 操作,如果 queue 沒有元素,輸出"The queue is empty.",否則請輸出被刪除的元素。

deque
- d.push_front(x)
- d.push_back(x)
- d.pop_front(x)
- d.pop_back(x)
- d.front()
- d.back()
- d.empty()
- d.size()

#include <bits/stdc++.h>
using namespace std;
int main(){
deque<int>Deque;
Deque.push_front(2);
Deque.push_front(1);
Deque.push_back(3);
//將東西放在deque的最前方或最後方
cout << "the front of the deque is " << Deque.front() << '\n';
// 1(回傳最前方的值)
cout << "the back of the deque is " << Deque.back() << '\n';
// 3(回傳最後方的值)
Deque.pop_front();
//刪除最前方的值
Deque.pop_back();
//刪除最後方的值
cout << "the front of the deque is " << Deque.front() << '\n';
// 2(回傳最前方的值)
cout << "the back of the deque is " << Deque.back() << '\n';
// 2(回傳最後方的值)
cout << "the size of the deque is " << Deque.size() << '\n';
//1(回傳deque現在有幾個元素)
for(int i = 0; i < Deque.size(); i++){
cout << Deque[i] << " ";
}
cout<<endl;
//隨機存取
while(Deque.empty() == false){
cout << "the deque is not empty !\n";
cout << "the front of the deque now is " << Deque.back() << '\n';
Deque.pop_back();
}
//清空deque
}
deque 練習


#include<bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int P, C, cs = 1;
while (cin >> P >> C && P != 0 && C != 0){
deque<int>d;
char command;
int s;
for (int i = 1; i <= min(P,C); i++){
d.push_back(i);
}
cout << "Case " << cs++ << ":"<<"\n";
while (C--){
cin >> command;
if (command == 'N')
{
cout << d.front() << "\n";
d.push_back(d.front());
d.pop_front();
}
else
{
cin >> s;
for (auto it = d.begin(); it != d.end(); it++){
if (*it == s)
{
d.erase(it);
break;
}
}
d.push_front(s);
}
}
}
}
set
-
只存node的紅黑樹(一種二元搜尋樹)
-
儲存的type需要可排序

- 將我們的資料丟進set中
- 判斷我們的資料是否在set中
- 若已存在的值不會被重複儲存
- s.insert(x) //將x插入set中
- s.count(x) //回傳x是否存在於set中
- s.erase(x) //刪除在set中的x
- s.clear() //刪除set中所有元素
- s.begin() //回傳set第一個元素的位置
- s.end() //回傳set最後一個個元素 + 1的位置
- s.empty()
- s.size()
#include <bits/stdc++.h>
using namespace std;
int main(){
set<int>Set;
Set.insert(1);
Set.insert(1);
Set.insert(1);
Set.insert(1);
Set.insert(2);
Set.insert(3);
//將東西存入set中
cout << "Set.count(1) = " << Set.count(1) << endl;
// Set.count(1) = 1
cout << "Set.count(10) = " << Set.count(10) << endl;
// Set.count(10) = 0
Set.erase(1);
//刪除set中的1
cout << "Set.count(1) = " << Set.count(1) << endl;
// Set.count(1) = 0
cout << "the size of the set is " << Set.size() << endl;
// 3(回傳set中的元素個數)
Set.clear();
//清空set中元素
cout << "the size of the set is " << Set.size() << endl;
// the size of the set is 0
if(Set.empty()){
cout << "the set is empty now !!"<<endl;
}
// the set is empty now!!
}
遍歷所有在set中的元素
- 利用iterator、begin()與end()
- 利用auto來遍歷
利用iterator、begin()與end()
#include <bits/stdc++.h>
using namespace std;
int main(){
set<int>Set;
Set.insert(1);
Set.insert(1);
Set.insert(1);
Set.insert(1);
Set.insert(2);
Set.insert(3);
set<int>::iterator iter;
for(iter = Set.begin(); iter != Set.end(); iter++){
cout << *iter << " ";
}
// 1 2 3
}
利用auto
#include <bits/stdc++.h>
using namespace std;
int main(){
set<int>Set;
Set.insert(1);
Set.insert(1);
Set.insert(1);
Set.insert(1);
Set.insert(2);
Set.insert(3);
for(auto it: Set){
cout << it << " ";
}
// 1 2 3
}
map
Title Text
- 紅黑樹(一種二元搜尋樹)
- 有key 與 value
- 將我們的key與value丟進map中
- key不能重複,value可以重複
- 用key就可以得到value
Key
value
001
Key
002
John
Bill
pair
- 一種資料型態,為兩種型態的組合
- 兩個個別的type可以不一樣
- 可利用first與second取值或建立
- 可利用make_pair來建立
pair
#include <bits/stdc++.h>
using namespace std;
int main(){
pair<string, int> p[2];
p[0] = make_pair("Hank", 891008);
p[1].first = "Catherine";
p[1].second = 900131;
cout << p[0].first << " " << p[0].second << '\n';
// Hank 891008
cout << p[1].first << " " << p[1].second << '\n';
// Catherine 900131
}
- m.insert(x) //將x插入map中
- m.count(x) //回傳x這個key是否在map中
- m.erase(x) //刪除在map中key為x的
- m.clear() //刪除map中所有元素
- m.begin() //回傳map第一個元素的位置
- m.end() //回傳map最後一個個元素 + 1的位置
- m.empty()
- m.size()
Map
#include <bits/stdc++.h>
using namespace std;
int main(){
map<int,string>Map;
Map.insert(make_pair(0, "Hank"));
//可以利用make_pair
Map[1] = "Catherine";
//也可以用類似陣列儲存的方式來儲存
cout << "Map.count(1) = " << Map.count(1) << '\n';
// Map.count(1) = 1
cout << "Map.count(2) = " << Map.count(2) << '\n';
// Map.count(2) = 0
Map.erase(0);
cout << "Map.count(0) = " << Map.count(0) << '\n';
// Map.count(0) = 0
cout << "the size of map is " << Map.size() << '\n';
// the size of map is 1
Map.clear();
if(Map.empty()){
cout << "the map is empty now !!\n";
}
//清空map
}
利用iterator、begin()與end()來遍歷
#include <bits/stdc++.h>
using namespace std;
int main(){
map<int, string>Map;
Map.insert(make_pair(0, "Hank"));
Map[1] = "Catherine";
Map[2] = "Linus";
Map[3] = "Jason";
Map[4] = "Jimmy";
map<int, string>::iterator it;
for(it = Map.begin(); it != Map.end(); it++){
cout << it->first << " " << it->second << " ";
}
// 0 Hank 1 Catherine 2 Linus 3 Jason 4 Jimmy
}
使用auto來遍歷
#include <bits/stdc++.h>
using namespace std;
int main(){
map<int, string>Map;
Map.insert(make_pair(0, "Hank"));
Map[1] = "Catherine";
Map[2] = "Linus";
Map[3] = "Jason";
Map[4] = "Jimmy";
for(auto it: Map){
cout << it.first << " " << it.second << " ";
}
// 0 Hank 1 Catherine 2 Linus 3 Jason 4 Jimmy
}
opeator overloading
- 因為有些資料結構的儲存要利用到可排序的資料,因此必須自訂排序規則
- 較常使用在sort、priority_queue
- STL中我們介紹的資料結構如set, map等若要自訂資料型態也須使用
struct
#include <bits/stdc++.h>
using namespace std;
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
};
operator overloading
bool operator < (const item& rhs) const{
// item代表左邊,rhs代表右邊
// return true 如果左右邊不需交換
// return false 如果左右邊要交換
}
希望x從大到小,
若x相同則y從大到小
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
//operator overloading
bool operator<(const item& rhs)const{
//若左邊的x比右邊的x大,不用交換位置,回傳true
if(x > rhs.x){
return true;
}
//若左邊的x與右邊的x相同,且左邊的y比右邊的y大,不用交換位置,回傳true
else if(x == rhs.x && y > rhs.y){
return true;
}
else{ //交換位置
return false;
}
}
};
希望x從大到小,
若x相同則y從大到小
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
//operator overloading
bool operator<(const item& rhs)const{
return x > rhs.x || (x == rhs.x && y > rhs.y);
}
};
#include <bits/stdc++.h>
using namespace std;
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
//operator overloading
bool operator<(const item& rhs)const{
return x > rhs.x || (x == rhs.x && y > rhs.y);
}
};
int main(){
vector<item>v;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 3; j++)
v.push_back(item(i, j));
sort(v.begin(), v.end());
for(auto it: v)
cout << it.x << " " << it.y << '\n';
}

priority queue
- heap
- 資料預設從大到小排序,從優先度高先取出
- 儲存的type需要可排序
- 在O(log(n))時間內維護最大/最小值
- pq.push(x)
- pq.pop() //刪除優先級最高元素
- pq.top() //回傳優先級最高元素
- pq.empty()
- pq.size()
priority queue
#include <bits/stdc++.h>
using namespace std;
int main(){
priority_queue<int>pq;
pq.push(1);
pq.push(2);
pq.push(5);
//將元素加入priority queue
cout << "pq.top() = " << pq.top() << '\n';
// pq.top() = 5
pq.pop();
//刪除priority queue中優先級最高元素
cout << "pq.top() = " << pq.top() << '\n';
// pq.top() = 2
cout << "pq.size() = " << pq.size() << '\n';
// pq.size() = 2
while(!pq.empty()){
pq.pop();
}
//清空priority queue
cout << "pq.size() = " << pq.size() << '\n';
// pq.size() = 0
}
讓priority_queue從小到大排
#include <bits/stdc++.h>
using namespace std;
int main(){
// 從小到大
priority_queue<int, vector<int>, greater<int>>pq;
pq.push(1);
pq.push(3);
pq.push(5);
while(pq.empty() == false){
cout << "pq.top() = " << pq.top() << endl;
pq.pop();
}
// pq.top() = 1
// pq.top() = 3
// pq.top() = 5
}
自定義priority queue儲存內容
- 使用struct來定義儲存的內容,必須定義出排序方式,才可以使用priority_queue
- 由於priority_queue預設是「從大到小」,所以我們的operator要寫「相反」(非常重要)
#include <bits/stdc++.h>
using namespace std;
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
//operator overloading
bool operator<(const item& rhs)const{
return x > rhs.x || (x == rhs.x && y > rhs.y);
}
};
int main(){
priority_queue<item>pq;
pq.push(item(4, 4));
pq.push(item(3, 2));
pq.push(item(4, 3));
pq.push(item(1, 2));
while(!pq.empty()){
cout << pq.top().x << " " << pq.top().y << endl;
pq.pop();
}
}
看看code,是看看會執行出什麼結果
#include <bits/stdc++.h>
using namespace std;
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
//operator overloading
bool operator<(const item& rhs)const{
return x > rhs.x || (x == rhs.x && y > rhs.y);
}
};
int main(){
priority_queue<item>pq;
pq.push(item(4, 4));
pq.push(item(3, 2));
pq.push(item(4, 3));
pq.push(item(1, 2));
while(!pq.empty()){
cout << pq.top().x << " " << pq.top().y << endl;
pq.pop();
}
}

#include <bits/stdc++.h>
using namespace std;
struct item{
int x, y;
//constructor
item(int x, int y):x(x), y(y){}
//operator overloading
bool operator<(const item& rhs)const{
return (x < rhs.x || (x == rhs.x && y < rhs.y));
}
};
int main(){
priority_queue<item>pq;
pq.push(item(4, 4));
pq.push(item(3, 2));
pq.push(item(4, 3));
pq.push(item(1, 2));
while(!pq.empty()){
cout << pq.top().x << " " << pq.top().y << endl;
pq.pop();
}
}

#include<bits/stdc++.h>
using namespace std;
int main(){
int n,num,a,b;
while(cin>>n&&n){
priority_queue<int,vector<int>,greater<int>>pq;
long long ans=0;
for(int i=0;i<n;i++){
cin>>num;
pq.push(num);
}
for(int i=0;i<n-1;i++){
a=pq.top();
pq.pop();
b=pq.top();
pq.pop();
ans+=(a+b);
pq.push(a+b);
}
cout<<ans<<endl;
}
}
感謝
-
Hank 學長110-2課程簡報
-
Mimmy 學姊110-2課程簡報
C++ intro & stl
By zonghao
C++ intro & stl
- 121