暑假資讀[3]
王政凱
講師介紹
- 227王政凱
- ck_platypus
- 建中資訊 學術兼外交
- 地科讀書會講師
- 我不會資訊
- FB:王政凱
- IG:@kennywang2017
基礎資料結構
What is 資料結構?
Data Structure,是電腦中儲存、組織資料的方式。
「陣列」即是一種最簡單的資料結構
1 | 10 | 2 | 4 | 19 | 22 | 22 | 5 | 7 | 11 |
---|
資料結構+演算法=程式
一位偉大的人曾經說過
Standard Template Library
- c++標準模板庫
- 簡稱STL
- 裡面有一大堆寫好的函式、容器
- 要用之前要先引入
- #include <你要的函式庫>
- 大家可以去c++.com尋寶
你的程式碼可能會長這樣
#include <iostream>
#include <algorithm>
#include <cmath>
#include <string>
#include <utility>
#include <bitset>
#include <climits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;
int main(){
return 0;
}
但也可以長這樣
#include <bits/stdc++.h>
using namespace std;
int main(){
return 0;
}
在開始講資料結構之前
iterator
- 迭代器
- 一種資料型態
- 儲存的是記憶體位置
- 和pointer十分相像
- 指向STL容器中的物件
- prev(it), it--
- next(it), it++
vector
\(\overrightarrow{v}=(x, y)\)
否
vector
又稱dynamic array,可以動態開記憶體
使用時機:
1.當你的二維陣列每個陣列長度不同
2.當你要將陣列傳進函式但你不會指標(我)
3.想讓程式碼色彩鮮豔
4.任何時候
宣告
vector<int> v1;
vector<int> v2(10);
vector<int> v3(1989, 64);
vector<int> v4={7, 1, 2, 2};
vector<vector<int> > vv[100]
引入
#include <vector>
#include <vector>
using namespace std;
int main(){
vector<int> v;
v.size();
bool emp=v.empty();
v.resize(n);
v[i] = x;
v.push_back(x);
v.emplace_back(x);
v.pop_back(x);
v.clear();
fill(v.begin(), v.end(), x);
sort(v.begin(), v.end());
int lb = lower_bound(v.begin(), v.end(), x)-v.begin();
int ub = upper_bound(v.begin(), v.end(), x)-v.begin();
return 0;
}
vector扣的
lower_bound
在一個已排序好的陣列(vector)裡面,
找到大於等於某數的最小元素的迭代器,
若不存在則回傳末位置之迭代器
upper_bound
在一個已排序好的陣列(vector)裡面,
找到大於某數的最小元素的迭代器,
若不存在則回傳末位置之迭代器
蛤~
怎麼做
二分搜
把陣列二等分,並判斷目標物應該在前半段還是後半段
1 | 3 | 4 | 6 | 8 | 10 | 12 | 13 |
---|
1 | 3 | 4 | 6 |
---|
8 | 10 | 12 | 13 |
---|
1 | 3 |
---|
4 | 6 |
---|
8 | 10 |
---|
12 | 13 |
---|
1
3
4
6
8
10
12
13
二分搜
使用時機:
若有某性質arr[i]符合則arr[j];j>=i也符合,
可以用二分搜快速找到符合此性質的第一個元素。
#include <vector>
using namespace std;
int main(){
vector<int> v={1,3,4,6,8,10,12,13};
int l=0, r=8, target=9;
while(l!=r){
int mid=(l+r)/2;
if(v[mid]>=target) r=mid;
else l=mid+1;
}
return 0;
}
二分搜扣的
例題
可以回去找之前陣列的例題自己玩玩看vector
先不要用lower_bound,大家自己寫寫看二分搜吧
沒那麼直覺的二分搜
沒那麼直覺的二分搜_2
pair
pair
就只是把兩個東西包起來
使用時機:
1.儲存平面坐標系上的點、向量
2.只有兩個東西寫struct很浪費
宣告
pair<int, int> p1;
pair<string, int> p2=make_pair("hsu", 69);
pair<int, int> p3={1911, 1010}
pair<pair<int, int>, int> p4=make_pair({1,2}, 3)
引入
#include <utility>
#include <utility>
#include <vector>
using namespace std;
int main(){
pair<int, int> p;
p.first = 1;
p.second = 2;
vector<pair<int, int> > v;
v.push_back(make_pair(1, 2));
v.push_back({3, 4});
v.emplace_back(5, 6);
return 0;
}
扣的
#include <utility>
using namespace std;
pair<int, int> operator+ (pair<int, int> a, pair<int, int> b){
return make_pair(a.first+b.first, a.second+b.second);
}
int main(){
pair<int, int> a=make_pair(1,2);
pair<int, int> b=make_pair(3,5);
cout << (a+b).first << " " << (a+b).second << endl;
//4 7
return 0;
}
自定義運算子扣的
例題
好像沒有只有pair的例題
No judge
請用運算子重載做出以下兩種運算
1.平面向量的內積
2.平面向量的外積
stack, queue, deque
stack, queue, deque
stack(堆疊):first_in_last_out
queue(佇列):first_in_first_out
deque(雙向佇列):顧名思義
宣告
stack<int> st;
queue<int> qu;
deque<int> dq;
引入
#include <stack>
#include <queue>
#include <deque>
#include <stack>
using namespace std;
int main(){
stack<int> st;
st.push(1);
int stt = st.top();
st.pop();
int stsz = st.size();
bool ste = st.empty();
return 0;
}
stack扣的
#include <stack>
using namespace std;
int main(){
int st[100], top = 0;
st[top++] = 1;
int stt = st[top-1];
top--;
int stsz = top;
bool stemp = (top==0);
return 0;
}
另一種stack扣的
#include <queue>
using namespace std;
int main(){
queue<int> qu;
qu.push(1);
int quf = qu.front();
int qub = qu.back();
qu.pop();
int qusz = qu.size();
bool stemp = qu.empty();
return 0;
}
queue扣的
#include <deque>
using namespace std;
int main(){
deque<int> dq;
dq.push_front(1);
dq.push_back(2);
int dqf = dq.front();
int dqb = dq.back();
dq.pop_front();
dq.pop_back();
int dqsz = dq.size();
bool stemp = dq.empty();
return 0;
}
deque扣的
例題
set
戰爭之神、風暴之神
否
set
集合,但STL中的set與數學上不同之處為其是有序的
支援的操作:
1.把元素丟進去集合(不重複)
2.尋找集合中大於等於某元素的最小元素
set
以上操作如果用陣列做,複雜度可做到以下兩種:
O(1)插入、O(n)查詢
O(n)插入、O(log n)查詢
好像不是很快
自己去查 Binary Search Tree
STL中的set可以做到O(log n)插入、O(log n)查詢
宣告
set<int> s;
multiset<int> ms
引入
#include <set>
#include <set>
using namespace std;
int main(){
set<int> s;
s.insert(1);
set<int>::iterator it=s.find(1);
int scnt = s.count(1);
s.erase(1);
s.erase(it);
for(int i:s){};
for(auto it=s.begin();it!=s.end();it++){};
int smin = s.begin();
int smax = s.rbegin();
int slb = s.lower_bound(1);
int sub = s.upper_bound(1);
int ssz = s.size();
bool semp = s.empty();
return 0;
}
set扣的
#include <set>
using namespace std;
int main(){
multiset<int> ms;
ms.insert(1);
ms.insert(1);
ms.insert(1);
int scnt = ms.count(1);
multiset<int>::iterator it=ms.find(1);
ms.erase(it);
ms.erase(1);
return 0;
}
multiset扣的
例題
map
map
跟set很像,但是每個元素為pair型態,
且find、erase、lower_bound等函式僅針對pair.first
可以把map想成是一對一映射的加強版set
宣告
map<int, int> m;
引入
#include <map>
#include <map>
using namespace std;
int main(){
map<int, int> m;
m.insert(1,2);
m[1]=2;
for(auto it=m.begin();it!=m.end();it++){
pair<int, int> = make_pair(it->first, it->second);
}
return 0;
}
map扣的(set有的map都有)
priority queue
priority queue
優先佇列,但事實上和queue沒啥關係
支援的操作:
1.把元素丟進去集合
2.尋找集合中最(大)值
3.刪除集合中最(大)值
()內判斷條件可自定義
priority queue
heap原理
構造一個完全二元樹,並保證父節點必(大)於子節點
21
20
18
11
9
7
4
5
2
13
6
3
heap原理(加入
從完全二元樹的末端插入元素,判斷是否(大)於父節點並交換
21
20
18
11
9
7
4
5
2
13
6
3
19
heap原理(加入
從完全二元樹的末端插入元素,判斷是否(大)於父節點並交換
21
20
18
11
9
7
4
5
2
19
6
3
13
heap原理(加入
從完全二元樹的末端插入元素,判斷是否(大)於父節點並交換
21
20
18
11
9
7
4
5
2
19
6
3
13
heap原理(加入
從完全二元樹的末端插入元素,判斷是否(大)於父節點並交換
21
20
18
11
9
7
4
5
2
19
6
3
13
heap原理(刪除
刪除根節點,並以最末位節點代替其位置,並往下重新調整
21
20
18
11
9
7
4
5
2
19
6
3
13
heap原理(刪除
刪除根節點,並以最末位節點代替其位置,並往下重新調整
20
18
11
9
7
4
5
2
19
6
3
13
heap原理(刪除
刪除根節點,並以最末位節點代替其位置,並往下重新調整
13
20
18
11
9
7
4
5
2
19
6
3
heap原理(刪除
刪除根節點,並以最末位節點代替其位置,並往下重新調整
13
20
18
11
9
7
4
5
2
19
6
3
#include <queue>
using namespace std;
struct cmp{
bool operator()(int a, int b){
return a<b;
}
};
int main(){
priority_queue<int> pq;
pq.push(1);
int pqt = pq.top();
pq.pop();
priority_queue<int, vector<int>, cmp> pq2;
return 0;
}
priority_queue扣的
例題
實作時間
C++標準模板庫
#include <algorithm>
using namespace std;
int main(){
int arr[10]={1,2,3,4,5,6,7,8,9,10};
swap(arr[1], arr[8]);
sort(arr, arr+10);
fill(arr, arr+10, 1);
int* lb = lower_bound(arr, arr+10, 1);
int* ub = upper_bound(arr, arr+10, 1);
int* maxx = max_element(arr, arr+10);
return 0;
}
#include<algorithm>
#include <cmath>
using namespace std;
int main(){
double a = abs(-5);
double b = ceil(3.4);
double c = floor(2.9);
double d = round(4.5);
double e = log(7122);
double f = log2(2147483648);//log(2147483648)/log(2);
double g = pow(2, 10);
double h = sqrt(7122);//pow(7122, 0.5);
double i = sin(2);
double j = cos(1);
double k = tan(3);
double l = asin(0.5);
double m = acos(-1);
double n = atan(-3);
double o = tgamma(10);//(n-1)!
return 0;
}
#include<cmath>
#include <complex>
using namespace std;
int main(){
complex<double> a(3, -4);
complex<double> b(-0.5, pow(3, 0.5)/2);
complex<double> c = a*b;
double d = real(c);
double e = imag(c);
double f = abs(c);
double g = arg(c);
return 0;
}
#include<complex>
#include <climits>
using namespace std;
int main(){
int int_min = INT_MIN;
int int_max = INT_MAX;
int unsigned_int_max = UINT_MAX;
long long int long_long_int_min = LLONG_MIN;
long long int long_long_int_max = LLONG_MAX;
long long int unsigned_long_long_int_max = ULLONG_MAX;
return 0;
}
#include<climits>
暑假資毒[3]
By ck_platypus
暑假資毒[3]
- 1,027