CPP[3]

基礎語法

章魚

INDEX

STL Review

Tuple

Set

Map

Algorithm

小社賽!!

STL Review

Pair

一、
pair<string,bool> p("小黑",false);
二、
p=make_pair("小黑",false);
三、
p.first="小黑";
p.second=false;

pair

first second
  • 對,它是對

Vector

  • 向量
  • 可伸縮的array
  • 可以用索引取值
  • push_back()
vector<int> v={1,4,2};
v.push_back(8);
v.push_back(5);
//v={1,4,2,8,5}

Iterator

for(vector<int>::reverse_iterator it=v.rbegin();it!=v.rend();it++){
        cout<<*it<<" ";
}

v(5)

v.rend()

1

5

2

4

8

5

8

2

4

1

output:

  • 迭代器

Iterator

for(auto it=v.rbegin();it!=v.rend();it++){
        cout<<*it<<" ";
}

用auto省略型態

for(auto i:v){
        cout<<i<<" ";
}

跑過每一個值

Stack

  • 堆疊
  • LIFO
  • push()

stk

1

2

4

Queue

  • 佇列
  • FIFO
  • push()

q

1

2

4

Queue

  • 佇列
  • FIFO
  • push()

q

4

1

2

Priority_queue

  • 優先權佇列
  • 預設大的在前
  • 也可自訂比較規則
  • push()

1

2

4

pq

Priority_queue

  • 優先權佇列
  • 預設大的在前
  • 也可自訂比較規則
  • push()

1

2

4

pq

Priority_queue

  • 優先權佇列
  • 預設大的在前
  • 也可自訂比較規則
  • push()

1

pq

List

  • 雙向鏈接串列
  • 數值+前後元素的指針
  • 不能索引取值但可用迭代器
  • push_back()&push_front

2

1

nullptr

nullptr

0x1429

0x1428

list<int> l={2,1}

0x1428

0x1429

tuple

上次忘了講: )

tuple

可以存更多東西的pair

tuple<string,int,double> t("do",48,7.63);

一樣宣告每個變數的型態

宣告

#include<tuple>

取值

.third

tuple<string,int,double> t("do",48,7.63);
cout<<get<1>(t);
//48

get<索引>(tuple名稱)

賦值

tuple<string,int,double> t("do",48,7.63);

auto t=make_tuple("do",48,7.63);

tuple<string,int,double> t;
get<0>(t)="do";
get<1>(t)=48;
get<2>(t)=7.63;

這三個等價

set

set

集合

每個元素只出現一次

像priority_queue一樣會排序

預設從小排到大

宣告

#include<set>

set<int> s;

.insert()

將值插入set

如果set中已經有它了

那啥都不會發生

set<int> s;
s.insert(4);//4
s.insert(8);//4,8
s.insert(7);//4,7,8
s.insert(4);//4,7,8

s

4

4

8

7

7

4

8

8

O(log n)

.count()

數某個值在set中的個數

∵不是0就是1阿

∴可以當bool用👀

s.count(1);//0
s.count(4);//1

s

7

4

8

O(log n)

.erase()

踢掉指定值

有踢掉->回傳True

沒有這個值->回傳false

cout<<s.erase(1);//0
if(s.erase(8)){
	cout<<888;
}//888

s

7

4

8

O(log n)

.size()

&

.empty()

you know

s

7

4

8

3

0

O(1)

.clear()

s.clear();
cout<<s.empty();//1

s

8

4

7

O(n)

查詢

不能用[索引]

不能用.top()

只能用迭代器遍歷

for (auto i:s) {
	cout << s << " ";
}//這種也行

unordered_set

unordered_set

不會根據優先權排序

語法跟set一樣

#include<unorder_set>

unordered_set<int> us;
us.insert(4);//4
us.insert(8);//4,8
us.insert(7);//4,8,7
set unordered_set
.insert() O(log N) O(1)
.erase() O(log N) O(1)
.count() O(log N) O(N)

multiset

multiset

可以有重複元素的set

語法也跟set一樣

#include<set>

multiset<int> ms;
ms.insert(4);//4
ms.insert(8);//4,8
ms.insert(7);//4,7,8
ms.insert(4);//4,4,7,8
set unordered_set multiset
排序 o x x
重複 x x o

map

map

一個key對應一個value

簡單來講

就是你可以自訂index的array

但他的index不一定要是int

喔對他也會排序(根據index)

宣告

#include<map>

map<key型態,value型態>

map<string,bool> m;

插入元素

map<string,bool> m;
m.insert({"小黑",false})
m.insert({"無語",false})//用大括弧包

m["小黑"]=false;
m["無語"]=false;

key(string)

value(bool)

小黑

無語

false

false

cout<<("小黑">"無語");
//0

O(log n)

取值

像array一樣,用index取值
cout<<m["小黑"];//false

遍歷
for(auto i:m){
	cout<<i.first<<' '<<i.second<<'\n';
}
//"小黑" false
//"無語" false

key(string)

value(bool)

小黑

無語

false

false

O(log n)

.clear()

m.clear()

key(string)

value(bool)

小黑

無語

false

false

O(n)

把map當vector用?

蛤?

吃飽太閒?

map<int,int> m;
m[0]=4;
m[3]=8;
m[5]=7;

來看個情況

vector<int> v(6);
v[0]=4;
v[3]=8;
v[5]=7;

0

0

2

1

index

value

3

5

0

0

0

7

4

4

8

8

7

5

4

3

把map當vector用?

map<int,int> m;
m[0]=4;
m[3]=8;
m[5]=7;
vector<int> v(4);
v[0]=4;
v[3]=8;
v[5]=7;

數據離散的時候

map較好

0

0

2

1

index

value

3

5

0

0

0

7

4

4

8

8

7

5

4

3

unordered_map

又是unordered

=>不排序的map

語法跟map基本一樣

#include<unordered_map>

map unordered_map
加key O(log N) O(1)
改值 O(log N) O(1)

algorithm

聽說這裡其實是演算法小社

今天還是沒有要講演算法

誒但是

來講STL的演算法

#include<algorithm>

min(a,b) & max(a,b)

回傳a,b中比較

小的/大的

int a=4;
int b=8;
cout<<max(a,b);//8
cout<<min(a,b);//4

min(a,b) & max(a,b)

只能比較兩個元素

int a=4;
int b=8;
int c=7;
cout<<max(a,max(b,c));//8

=>在max裡面包max

要比三個怎麼辦

swap(a,b)

交換a,b

a,b是STL也行

但變數型態要相同

int a=4;
int b=8;
swap(a,b);
cout<<a;//8

reverse

交換一個範圍內的元素

vector<int> v;
for(int i=0;i<10;i++) v.push_back(i);
//0,1,2,3,4,5,6,7,8,9
reverse(v.begin()+2,v.end());
//0,1,9,8,7,6,5,4,3,2

v

0

v.begin()

v.begin()+2

v.end()

1

3

3

6

6

9

9

2

2

8

8

7

7

5

5

4

4

這是去年你們學長的學長的學長遇到的困擾

這是去年你們學長的學長的學長的學長的簡報

這是今年你們學長的簡報

明年的學術,你知道該怎麼做了吧

深色主題重磅回歸

(學長的)*3在說什麼

排序一串數字v

假設學長想要由小到大

比較v[0]和v[1]

交換v[0]和v[1]

如果v[1] >= v[0]

比較此時的v[1]和v[2]

一樣視情況交換

重複這個操作

但你會發現

重複到容器尾端後

還是沒排好

5,4,3,2,1

舉例來說

經過一輪操作

變成4,3,2,1,5

但你會發現

所以你要重複n輪

for(int i=0;i<v.size();i++){
	for(int j=0;j<v.size()-i-1;j++){
    	if(v[j]>=v[j+1]){
        	swap(v[j],v[j+1]);
        }
    }
}

順便講一下這是bubble sort

阿不小心講到演算法了

O(n²)

沒聽懂?

那也沒關西

來講個簡單又快速的好用工具

sort()

O(n log n),超快

sort()

如果要達到上面的效果

sort(v.begin(),v.end());

一行解決ㄝ超讚

sort()

sort(迭代器,迭代器,自訂比較函式)

bool comp(int a,int b){
	return a<b;
}
vector<int> v={4,8,7,6,3};
sort(v.begin()+1,v.end(),comp);
//{4,3,6,7,8}

跟priority_queue一樣可自訂

但sort預設是從小到大

custom comparators

自訂比較器

priority_queue<int,vector<int>,comp> pq;
sort(v.begin(),v.end(),comp);

是他

也是他

自訂比較器

自己定義排序規則

主要分三種:

函數指針

仿函數

little difference

#include<bits/stdc++.h>
using namespace std;
struct comp{
    bool operator()(int a,int b){
        return a<b;
    }
};
int main(){
    priority_queue<int,vector<int>,comp> pq;
}
#include<bits/stdc++.h>
using namespace std;
bool comp(int a,int b){
	return a<b;
}
int main(){
  vector<int> v={4,8,7,6,3};
  sort(v.begin(),v.end(),comp);
}

sort

priority_queue

函數指針

仿函數

我是sort但我想用仿函數

#include<bits/stdc++.h>
using namespace std;
struct comp{
    bool operator()(int a,int b){
        return a<b;
    }
};
int main(){
    vector<int> v={4,8,7,6,3};
    sort(v.begin(),v.end(),comp());
}

加個小括弧

原理部分這邊就不提了

總之他們有差

不要像我一樣被CE卡

還是那句

想知道自己去cplusplus.com

TIOJ

1682

NEOJ

2024

1111

0059

0020

0021

ISCOJ

4476

4477

題單

來烤肉!!

點我

現在開放外校&高二生了耶

找你的好朋友一起來吧

c++語法小社2

By oct0920

c++語法小社2

  • 233