南大附中資訊研究社

NFIRC 1ST

第 9 次社課講義

2024/03/20 → 2024/04/03

講者:YuDong

🎄應該是進階班的課程

🎄進階班主要在做啥?

  • 以程式競賽為主要
  • 你會學到競程上的技巧、觀念、原理等
  • 比起語法班會有更深的內容
  • 實力取決於你的練習量

🎄現在退出還來的及嗎

  • 欸?我不知道

目錄

  • STL Intro
  • STL Container
    • vector
    • pair & tuple
    • stack
    • queue
    • set
    • map

STL Introduction

什麼是 STL

  • Standard Template Library

  • 標準模板庫

什麼是 STL

  • Standard Template Library

  • 標準模板庫
  • 提供 模板類別 & 函式

什麼是 STL

  • Standard Template Library

  • 標準模板庫
  • 提供 模板類別 & 函式
  • 這堂課的重點會著重於

Container 容器(資料結構)

什麼是 STL

  • Standard Template Library

  • 標準模板庫
  • 提供 模板類別 & 函式
  • 這堂課的重點會著重於

Container 容器(資料結構)

所以 iterator 迭代器只會稍稍提及一下!

什麼是

Container 容器(資料結構)

//array 陣列
int ary[10];
int 2d_ary[10][10];

//string 字串
string s;
  • 用來儲存資料的工具

STL Container 語法

container<type> name;

  • container: STL 容器型態

  • <type>: 容器內的元素型別

  • name: 這個容器叫什麼名字

宣告

//以往我們宣告陣列
int ary[45];

//declare
vector<int> v;
set<double> st;

vector

動態陣列

vector

動態陣列

可以動態調整長度的陣列

vector

vector<type> name;

宣告語法

vector

#include<vector> 
//標頭檔

//basic declare
vector<int> v;

varName(size);

vector<int> vec(3);
// [0, 0, 0]

varName(size,value);

vector<int> vec(4,2);
// [2, 2, 2, 2]

varName = {a, b, c}

vector<int> team = {1, 3, 5};
//[1, 3, 5]

vector

Methods:

Description

時間複雜度

.push_back(val)
.size()
.emplace_back(val)
.resize(n)
.clear()
.begin()
.end()

取得陣列大小

在最後方插入val
在最後方插入val
調整陣列長度為n
清空該陣列
陣列裡第一個資料的位置
陣列裡最後一個資料位置的後一位位置
O(1)
O(1)
O(1)
O(|size-n|)
O(size)
O(1)
O(1)
.front()
陣列最前面的元素
.front()
陣列最後面的元素
O(1)
O(1)

vector

用一張圖來解釋 vector 的話:

vector

//法一:
for(int i = 0; i < n; ++i) {
	cout << v[i] << " ";
}
//法二:
for(auto x: v) {
	cout << x << " ";
}

vector 的遍歷

法二的部分,日後有機會再詳談

可以先記他的用法 :D

vector

vector<int> v;
vector<int> example(3); //分配好空間大小

for(int i = 0; i < 3; ++i) {
	cin >> example[i]; 
    //分配好空間的 vector 可以像一般陣列一樣輸入
}

for(int i = 0; i < 5; ++i) {
	v.push_back(i);
    //v: [0,1,2,3,4]
}

for(int i = 0; i < 5; ++i) {
	cout << v[i] << " "; //0 1 2 3 4
}

cout << v[2] << "\n"; //2

寫起來的話長這樣子:

vector

pair

數對

將兩個元素型別包起來!

pair

宣告語法

pair<a, b> name;

資料型別:

如 int, char, double等
//標頭檔
#include<utility>
pair<int, int> ppl;
//pair<type1, type2> name;

pair<int, int> xd = {210, 211};
pair<int, int> xp(29,28);

xd.first; //210
xp.second; //28

pair<pair<int, char>, int> super = {{2,a},9};

super.first; //{2, a}
super.first.first; // 2
super.second; //9

pair

pair

vector<pair<int, int> > vpp;
vpp.push_back(make_pair(2,3));
vpp.push_back({4,3});
vpp.emplace_back(4,3);

pair

pair 常常與其他容器結合!

這裡以剛剛教過的 vector 舉例:

pair

pair

a915 解題提示:

輸入到 pair 中
然後用 sort() 方法排序
vector<pair<int ,int> > v;

for(int i = 0; i < n; ++i) {
	int x,y; cin >> x >> y;
    v.emplace_back(x,y);
    //or v.push_back({x,y}); 也可以
}

sort(v.begin(), v.end());
大致上長這樣
忘記 sort() 怎麼用的可以找一下之前的講義

stack

我們通常叫他「堆疊

stack 有一個特性:LIFO

Last In First Out

先進後出

stack

我們通常叫他「堆疊

stack 有一個特性:LIFO

Last In First Out

stack

stack

可以把它想像成一疊盤子、書之類的

stack

#include <stack>
stack<int> st;
//stack<type> name;

常用方法

.size()
.push(val)
.pop()
.top()

​.empty()

說明

取得stack的長度
新增 val 到頂端
移除最頂端元素
查看最頂端元素
確認是否為空

stack

stack

k612 解題提示:
stack 只放 '(' 跟 '['
然後去比對字串中,第 i 個字元是什麼

我們利用圖解來看一下這題的實作原理吧!

stack

for(int i = 0; i < s.size(); i++) {
	if(s[i] == '(' || s[i] == '[' || st.empty()) st.emplace(s[i]);
	else if(!st.empty()) {
		if( (st.top() == '(' && s[i] == ')') || (st.top() == '[' && s[i] == ']') ) 
        	st.pop();
		else break;
	}
}

k612 題解提示:

queue

他叫「(ㄓㄨˋ)

有些人說隊列

First In First Out

queue 有一個特性:FIFO

queue

他叫「(ㄓㄨˋ)

有些人說隊列

First In First Out

queue 有一個特性:FIFO

先進先出

queue

可以把它想像成排隊的人群隊伍

queue

#include <queue>
queue<int> qq;
//queue<type> name;

常用方法(與stack 相似)

.size()
.push(val)
.pop()
.front()
.back()

​.empty()

說明

取得queue的長度
新增 val 到尾端
移除最前端元素
查看最前端元素

查看最尾端元素

確認是否為空

queue

參照上一頁的幾個 Methods 就可以做出來了!

非線性資料結構

前面介紹的都是線性資料結構
其操作的複雜度通常都是 O(1) 或者 O(n)

非線性資料結構

前面介紹的都是線性資料結構
其操作的複雜度通常都是 O(1) 或者 O(n)
接下來要介紹一些非線性資料結構
課程因時間因素還有難度上的調整
只會先介紹 set 跟 map
實際上還有許多非線性資料結構,如:
priority_queue, multiset, unordered_map 

set

集合

不會有重複的元素

支援快速 搜尋、修改(插入、移除)

O(log\ n)

平衡二元樹的紅黑樹

set

  • insert(val)
  • erase(val)
  • count(val)
  • find(val)
  • lower_bound(val)
  • upper_bound(val)
插入 val 到 set 當中
將元素刪除
尋找 val 在 set 中出現的數量
(實際回傳只會有 1 or 0)
尋找 val 的位置
找第一個大於等於 val 的值的位置
找第一個大於 val 的值的位置

常用方法與說明

set

set<int> st;

for(int i = 0; i < 5; ++i) {
	st.insert(i);
}

for(auto it = st.begin(); it != st.end(); it++) {
	cout << *it << " ";
}//0 1 2 3 4

for(auto x : st) {
	cout << x << " ";
}//0 1 2 3 4

set

set

set 裸題
運用前面提到的 Method 即可解出

set

set<int> st;
while(n--) {
	int x;cin >> x;
	st.insert(x);
}		
cout << st.size() <<endl;
for(auto it:st) cout << it << " ";
cout << endl;

map

映射

沒有重複的 key-value pair

 

 搜尋 , 插入 , 移除 元素

O( \log n )

map

  • insert(val)
  • erase(val)
  • find(val)
    
  • lower_bound(val)
  • upper_bound(val)

插入 val 到 set 當中
將元素刪除
尋找 val 的位置
找第一個大於等於 val 的值的位置
找第一個大於 val 的值的位置

常用方法與說明

map

#include <map>
map<int ,string> mp;
//map<type1, type2> name;

mp[3] = "test";

map<string, int> ms;
ms["Wang"] = 35;

map

可以把 map 理解成是一把鑰匙對應一道門

key

value

map

可以把 map 理解成是一把鑰匙對應一道門

key

value

例如:

座號 27 號 - 小明

key

value

map

可以把 map 理解成是一把鑰匙對應一道門

key

value

例如:

座號 27 號 - 小明

正常情況來說,一個班級只會有一個 27 號

正好與 map 的概念有點像

key

value

map

STL Container 告一段落

STL Container 告一段落

STL Container 告一段落

STL Container 告一段落

接下來?

STL Container 告一段落

STL Container 告一段落

STL Container 告一段落

接下來?

多練習+補完其他沒講到的容器

還有一些實作細節

如 iterator

STL Container 告一段落

STL Container 告一段落

STL Container 告一段落

接下來?

多練習+補完其他沒講到的容器

還有一些實作細節

如 iterator

礙於時間因素沒辦法完整介紹

有任何問題都歡迎詢問~

回家自己練習的時候也可以私訊我 Discord 或其他聯繫管道!

第 9 次社課講義

By Dong Yu

第 9 次社課講義

  • 117