陣列
將同資料型態的值存在一起
宣告
和變數很類似
要在宣告同時設定陣列大小
也能預設值
#include <iostream>
using namespace std;
int main() {
int a[100];
int b[5] = {1, 5, 20, 14, 30};
}
使用
在要使用的陣列名稱後加索引值(index)
程式語言都是從0開始
索引值可以是變數
#include <iostream>
using namespace std;
int main() {
int a[5] = {1, 5, 20, 14, 30};
cout << a[0] << '\n'; //輸出1
cout << a[3] << '\n'; //輸出14
for(int i = 0; i < 5; i++){
cout << a[i] << " ";
}
}
輸入
通常搭配for迴圈來輸入
#include <iostream>
using namespace std;
int main() {
int a[5];
for(int i = 0; i < 5; i++){
cin >> a[i];
}
for(int i = 0; i < 5; i++){
cout << a[i] << " ";
}
}
改值
#include <iostream>
using namespace std;
int main() {
int a[5] = {2, 12, 15, 52, 17};
a[0] = 26;
a[1] = 78;
for(int i = 0; i < 5; i++){
cout << a[i] << " ";
}
}
和陣列的使用非常類似
例題
多維陣列
陣列裡放陣列(?
宣告
幾維就打幾個陣列大小
幾乎跟一維的宣告一模一樣
#include <iostream>
using namespace std;
int main() {
int a[1000][100];
int b[3][2] = {{1, 4}, {2, 4}, {14, 14}};
}
使用
和一維的一模一樣
再次提醒程式的index都是從0開始
#include <iostream>
using namespace std;
int main() {
int a[3][2] = {{1, 4}, {3, 7}, {17, 14}};
cout << a[0][0] << '\n'; //輸出1
cout << a[2][1] << '\n'; //輸出14
for(int i = 0; i < 3; i++){
for(int j = 0; j < 2; j++){
cout << a[i][j] << " ";
}
cout << '\n';
}
}
輸入and改值
跟一維的一模一樣

小提醒
陣列的大小是有限的
一維大概只到4*10^8
二維大概只到2*10^4
陣列宣告的地方會影響到最大的容量
如果你需要用到算大的空間
請宣告成全域
#include <iostream>
using namespace std;
int a[100000005];
int main() {
cout << "Hello world!";
}
#include <iostream>
using namespace std;
int main() {
int a[100000005];
cout << "Hello world!";
}
全域宣告,能順利執行
區域宣告,無法順利執行
例題
函式
自定義功能的東東
宣告
要宣告在main函式外
前面放回傳的資料型態
後面放函式的名稱
小括號記得打
大括號裡放要執行的程式
#include <iostream>
using namespace std;
//格式如下
//回傳的資料型態 名稱(){
// 執行的程式
//}
int hello(){ //其實這是不太正確的寫法
cout << "Hello World!";
}
int main() {
hello();
}
回傳return
會回傳一個數值並結束整個函式
資料型態為函式宣告的
#include <iostream>
using namespace std;
//格式如下
//回傳的資料型態 名稱(){
// 執行的程式
// return 數值
//}
int year(){
return 2022;
}
string hello(){
return "Hello World!";
}
int main(){
cout << year() << '\n';
cout << hello() << '\n';
}
參數
小括號裡可以放多個參數
參數只會在函式裡生效
#include <iostream>
using namespace std;
//格式如下
//回傳的資料型態 名稱(參數1, 參數2){
// 執行的程式
// return 數值
//}
int add(int a, int b){
return a + b;
}
bool equal(int a, int b){
if(a == b)
return true;
return false;
}
int main(){
cout << add(5, 10) << '\n';
if(equal(10, 1))
cout << "兩數相等" << '\n';
else
cout << "兩數不相等" << '\n';
//cout << a; //會報錯
}
如果參數有預設值可以不用傳入
#include <iostream>
using namespace std;
//格式如下
//回傳的資料型態 名稱(參數1, 參數2){
// 執行的程式
// return 數值
//}
int multiply(int a, int b, int c = 1){
return a * b * c;
}
int main(){
cout << multiply(2, 3);
}
無回傳函式
資料型態的位置打void
return後面直接打分號就好
#include <iostream>
using namespace std;
void hello(){
cout << "Hello world!\n";
return;
}
void add(int a, int b){
cout << a + b << '\n';
return;
}
int main() {
hello();
add(3, 6);
}
補充:遞迴
讓函式自己呼叫自己
ex:費式數列
練習
struct
自定義資料型態
宣告
struct後面放名稱
大括號裡放要的變數
大括號後記得加分號
也可以預設值
#include <iostream>
using namespace std;
int main() {
struct struct1{
int x, y;
};
struct1 a, b = {5, 10};
cin >> a.x >> a.y;
cout << a.x << " " << a.y << '\n';
cout << b.x << " " << b.y << '\n';
}
可以在分號前宣告
#include <iostream>
using namespace std;
int main() {
struct struct1{
int x, y;
}a, b = {5, 10};
cin >> a.x >> a.y;
cout << a.x << " " << a.y << '\n';
cout << b.x << " " << b.y << '\n';
}
struct內也能放函式
跟一般函式的宣告和使用方法一樣
#include <iostream>
using namespace std;
int main() {
struct struct1{
int x, y;
int f(int z){
return (x + y) * z;
}
}a;
int tmp;
cin >> a.x >> a.y;
cin >> tmp;
cout << a.f(tmp);
}
解題思維
僅供參考
加碼!!!
1.看懂題目
一定要完全懂題目要幹嘛
建議推導一遍範例輸入輸出
ex: zerojudge b266
2.拆解問題
將題目要做的事情一件一件拆開
每件事情分開思考怎麼做
最後再合在一起
ex: zerojudge h082
3.開始實作
實作剛剛拆解完的問題
可以分成很多函式來做
出問題的時候可以針對函式debug
練習
STL
好用的模板庫
vector
不用宣告大小的陣列
支援index查詢
能夠一直往後延伸或從後面刪除
需要引入函式庫<vector>
vector宣告
要預設大小在後面加(),裡面打數字
要再預設值的在大小後再打數字
格式如下
#include <iostream>
#include <vector>
using namespace std;
int main() {
//vector <資料型態> 名稱(預設大小,預設值)
vector <int> a;
vector <int> b(100); //預設大小為100
b[5] = 5;
cout << b[5] << '\n';
vector <int> c(100, 3); //預設大小為100且全部預設值為3
c[20] = 20;
cout << c[10] << " " << c[20] << '\n';
}
vector新增和刪除
push_back()為在尾端新增,在()裡打要新增的值
pop_back()為刪除尾端的值,括號裡不用放東西
back()為回傳尾端的值,括號裡不用放東西
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector <int> a;
a.push_back(2);
a.push_back(5);
cout << a.back() << '\n';
a.pop_back();
cout << a.back() << '\n';
a.push_back(10);
a.push_back(7);
cout << a[0] << " " << a[1] << " " << a[2] << '\n';
}
vector長度
size()為回傳vector的長度
但回傳的東西不是int或long long
要先轉型態
#include <iostream>
#include <vector>
using namespace std;
int main() {
vector <int> a;
a.push_back(2);
a.push_back(5);
cout << (int)a.size() << '\n';
a.push_back(4);
a.pop_back();
a.push_back(17);
cout << (int)a.size() << '\n';
}
stack
跟vector的概念幾乎一樣
只是少了index查詢
函式的名稱稍微不同
要引入函式庫<stack>
stack宣告
跟vector一樣
但無法預設大小和值
格式如下
#include <iostream>
#include <stack>
using namespace std;
int main() {
//stack <資料型態> 名稱
stack <int> a;
}
stack新增和刪除
push()為在頂端新增,在()裡打要新增的值
pop()為刪除頂端的值,括號裡不用放東西
top()為回傳頂端的值,括號裡不用放東西
#include <iostream>
#include <stack>
using namespace std;
int main() {
//stack <資料型態> 名稱
stack <int> a;
a.push(12);
a.push(4);
cout << a.top() << '\n';
a.pop();
cout << a.top() << '\n';
}
stack長度
跟vector一模一樣
STL的資結幾乎都長這樣
#include <iostream>
#include <stack>
using namespace std;
int main() {
//stack <資料型態> 名稱
stack <int> a;
a.push(12);
a.push(4);
cout << a.top() << '\n';
a.pop();
cout << a.top() << '\n';
cout << (int)a.size() << '\n';
}
例題
queue
先進先出
像排隊一樣
需引入函式庫<queue>
queue宣告
跟其他stl幾乎一樣
格式如下
#include <iostream>
#include <queue>
using namespace std;
int main() {
//queue <資料型態> 名稱
queue <int> a;
}
queue新增和刪除
push()為在後端新增,在()裡打要新增的值
pop()為刪除前端的值,括號裡不用放東西
front()為回傳前端的值,括號裡不用放東西
#include <iostream>
#include <stack>
using namespace std;
int main() {
//stack <資料型態> 名稱
stack <int> a;
a.push(12);
a.push(4);
cout << a.top() << '\n';
a.pop();
cout << a.top() << '\n';
}
queue長度
跟前面一模一樣
#include <iostream>
#include <queue>
using namespace std;
int main() {
//queue <資料型態> 名稱
queue <int> a;
a.push(12);
a.push(4);
cout << a.front() << '\n';
a.pop();
cout << a.front() << '\n';
cout << (int)a.size() << '\n';
}
deque
雙向的queue
可以在前端新增也能在後端新增
刪除也是
需引入函式庫<deque>
deque宣告
沒什麼好說的
格式如下
#include <iostream>
#include <deque>
using namespace std;
int main() {
//deque <資料型態> 名稱
deque <int> a;
}
deque新增和刪除
push_back()為在後端新增,在()裡打要新增的值
push_front()為在前端新增,在()裡打要新增的值
pop_back()為刪除後端的值,括號裡不用放東西
pop_front()為刪除前端的值,括號裡不用放東西
front()為回傳前端的值,括號裡不用放東西
back()為回傳後端的值,括號裡不用放東西
例題
set
儲存不重複的資料
會自動排序
結構為紅黑樹(二元搜尋樹)
需引入函式庫<set>
set宣告
一樣沒什麼好說的
格式如下
#include <iostream>
#include <set>
using namespace std;
int main() {
//set <資料型態> 名稱
set <int> a;
}
set使用
insert()為新增,在()裡打要新增的值
erase()為刪除,在()裡打要刪除的值
count()會回傳()裡的值是否在set裡
#include <iostream>
#include <set>
using namespace std;
int main() {
//set <資料型態> 名稱
set <int> a;
a.insert(1);
a.insert(2);
if(a.count(2))
cout << "2 in set\n";
else
cout << "2 not in set\n";
if(a.count(5))
cout << "5 in set\n";
else
cout << "5 not in set\n";
a.erase(2);
if(a.count(2))
cout << "2 in set\n";
else
cout << "2 not in set\n";
}
set遍歷
用for(auto :)達成
在遍歷時盡量不要修改set的資料
範例如下
#include <iostream>
#include <set>
using namespace std;
int main() {
set <int> a;
a.insert(5);
a.insert(2);
a.insert(14);
a.insert(2);
for(auto i : a){
cout << i << '\n';
//a.erase(2); 這行會爛掉
}
}
pair
由兩個資料型態加起來的STL
有順序之分
pair宣告
和前面的STL宣告很類似
要注意有兩種資料型態
#include <iostream>
using namespace std;
int main() {
//pair <資料型態1, 資料型態2> 名稱
pair <int, string> a;
}
pair使用
first為第一種資料型態,second為第二種
#include <iostream>
using namespace std;
int main() {
//pair <資料型態1, 資料型態2> 名稱
pair <int, string> a;
cin >> a.first >> a.second;
cout << a.first << " " << a.second << '\n';
a.first += 5;
a.second = "Hi";
cout << a.first << " " << a.second << '\n';
}
pair也可以宣告成陣列
範例如下
#include <iostream>
using namespace std;
int main() {
pair <int, string> a[3];
for(int i = 0; i < 3; i++){
cin >> a[i].first >> a[i].second;
}
a[0].first += 10;
a[1].first *= 2;
a[2].second = "good";
for(int i = 0; i < 3; i++){
cout << a[i].first << " " << a[i].second << '\n';
}
}
例題
map
由一個關鍵字(key)對應到一個值(value)
會依照key自動排序
可以理解成set的pair版
需引入函式庫<map>
map宣告
須分別宣告key跟value的資料型態
跟pair一樣
#include <iostream>
#include <map>
using namespace std;
int main() {
//map <key資料型態, value資料型態> 名稱
map <string, int> a;
}
map使用
可以直接在[]內打key
然後用=賦值
#include <iostream>
#include <map>
using namespace std;
int main() {
//map <key資料型態, value資料型態> 名稱
map <string, int> a;
a["aaa"] = 10;
a["abc"] = 15;
a["cjsj"] = 1;
cout << a["aaa"] << " " << a["abc"] << '\n';
//cout << a[1] << '\n';
//cout << a["adad"] << '\n';
}
map遍歷
跟set一樣用for(auto :)達成
但auto出的資料型態是pair
範例如下
#include <iostream>
#include <map>
using namespace std;
int main() {
//map <key資料型態, value資料型態> 名稱
map <int, char> a;
a[14] = 'A';
a[20] = 'c';
a[4] = 'V';
a[78] = 'l';
for(auto i : a){
cout << i.first << " " << i.second << '\n';
}
}
priority_queue
優先度最高的會在頂端
預設為最大值
結構為heap(堆疊)
需引入函式庫<queue>
priority_queue宣告
跟前面的stl一模一樣
範例如下
#include <iostream>
#include <queue>
using namespace std;
int main() {
//priority_queue <資料型態> 名稱;
priority_queue <int> a;
}
priority_queue使用
push()為放入()中的值
pop()為刪除頂端的值
top()會回傳頂端的值
#include <iostream>
#include <queue>
using namespace std;
int main() {
//priority_queue <資料型態> 名稱;
priority_queue <int> a;
a.push(5);
a.push(21);
cout << a.top() << '\n';
a.pop();
a.push(2);
cout << a.top() << '\n';
}
如果要最小值在頂端?
1.把push的值加個負號,拿出來時再加回去
2.在宣告時加點東西,範例如下
#include <iostream>
#include <queue>
using namespace std;
int main() {
//priority_queue <資料型態, vector<資料型態>, greater<資料型態>> 名稱;
priority_queue <int, vector<int>, greater<int>> a;
a.push(5);
a.push(21);
cout << a.top() << '\n';
a.pop();
a.push(2);
cout << a.top() << '\n';
}
例題
期末練習題
C++語法2
By patrickh
C++語法2
- 468