# C++ 自主學習的紀錄
#include <iostream> 跟 using namespace std: 筆記中省略
## 指標
```cpp=
int n;
//&n 表n的位址
int *p=&n; //*p為指標且p是n的位址
*p=10; //用*p提取p處的值,若修改*p則n亦改變
int *p=0; //不知為何定義時似乎只能用0或是&n
//p+1:0x4 int每次+4(16進位),而double則是8,etc.,陣列中亦然
int **pp=&p; //指標的指標
int arr[1][2][3]={{...},{...}};
int (*p)[2][3]=arr;//n層陣列的指標,要宣告n-1層的陣列,但其實有點看不太懂,上面也說用auto比較方便
int *p = new int(100); //建立位址並賦予儲存值用new
delete p; //刪除該項空間用delete
```
## vector
線性、長度可變
```cpp=
#include <vector>
vector <int> v={1,2,3}; //有點像陣列
vector <int> v0(v); //複製一個一樣的,同......v0=v
s=v.size();// 得知元素個數
e=v.empty();// 得知是否為空
f=v.front();// 取得第一個元素
b=v.back();// 取得最後的元素
v.push_back(n)// 新增元素到最後
v.pop_back();// 取出back
v.clear();// 清空
//主題外學到的
auto n=10 //自動判斷資料型態
auto a[]={...} //也可以用向量 vector <auto> a{...}
for (auto b:a) //每次的b分別對應a的值,做a的長度次
{
cout << b << endl; 輸出a的每一項
}
#include <algorithm> //其中的sort跟find的部分用法
sort (a.begin(),a.end()) //把a排序,兩個位置是起點跟終點
f=find (a.begin(),a.end(),1); //在a中找1,起點終點和目標,若a中無1,則f將為a的最後一項
```
## stack
堆疊,可變、線性、可從最後面拿出or放入資料
```cpp=
stack<int> s,s1;//宣告stack
s.push(z);從最後放入z
s.pop();拿掉最後的
e=s.empty();檢查是否為空
s.swap(s1);交換兩組數據
si=s.size();查看數量
t=s.top();看最後一項
```
## array
線性、長度不變
```cpp=
#include <array>
array<int,5> number; //長度5的array
s=a.size();// 得知元素個數
e=a.empty();// 得知是否為空,可是不知為何,只有在長度為0時會被判斷為空
f=a.front();// 取得第一個元素
b=a.back();// 取得最後的元素
a.fill(n);// 設定a中元素為n
//大致上跟vector差不多,但是無法改變長度,宣告時要宣告長度,無改變長度的方法
```
## string
```cpp=
#include <string>
string s1; //空的
string s2("abc"); //內容是abc
string s3(s2); //內容跟s2一樣 意思同 string s3=s2;
string s4="abc"; //內容是abc
/*
s.size()、s.length() 取得字串長度
s.empty() 是否為空
可用==比較兩string內容是否相同
*/
//可string=char[],但不可char[]=string
s2=s2+"xyz" //s2會變成abcxyz
s2=s2+"/n" //變成abcxyz換行
s2[0]//a
s2[1]//b用法同char[]
for (auto n:s2)
{
cout << n;
}//可用for range 語法
```
## algoriyhm(有與vector的組合)
```cpp=
#include <algorithm>
#inlcude <vector>
//互換(swap)
swap(a,b);//交換a&b值
//排序(sort)及反轉(reverse)vector
vector <int> v;
v={1,2,6,7,85,201,35,67};
sort(v.begin(),v.end());
reverse(v.begin(),v.end());
//v.begin()跟v.end()是指標
//排序及反轉陣列
int v[]={1,2,6,7,85,201,35,67};
sort(v,v+sizeof(v)/sizeof(int));
reverse(v,v+sizeof(v)/sizeof(int));
/*sort&reverse 括號中前面的v好像是因為v[]是陣列,所以v會等同於&v[0],
該v會變成指該陣列的第一個數字的指標而sizeof(v)則會看v用了多少空間(4*8),
除以sizeof(int)也就是4以後就會陣列長度,所以此處也可以直接輸入v+8。*/
//upper bound & lower bound
//陣列版本
int v[]={1,2,6,7,85,201,35,67};
sort(v,v+sizeof(v)/sizeof(int));
int x=85;
int *l = lower_bound(v,v+sizeof(v)/sizeof(int),x);
int *u = upper_bound(v,v+sizeof(v)/sizeof(int),x);
cout << "lower bound is " << *l << endl;
cout << "upper bound is " << *u << endl;
//lower bound 是找v至v+sizeof(v)/sizeof(int)中,>=x的值,upper bound則是>x的
//需先將v由小至大排序
//vector版本
vector <int> v;
v={1,2,6,7,85,201,35,67};
v.begin(),v.end());
int x=85;
auto l = lower_bound(v.begin(),v.end(),x);
auto u = upper_bound(v.begin(),v.end(),x);
cout << "lower bound is " << *l << endl; endl;
```
## 算交點
輸入n條線
然後分別輸入每條線的a,b,c(ax+by=c)
輸出每個交點
```cpp=
#include <iostream>
using namespace std;
int main()
{
int n,i,j,k;
cin >> n;
float a[n],b[n],c[n];
for (i=0;i<n;i++)
{
cin >> a[i] >> b[i] >> c[i];
}
for (i=0;i<n;i++)
{
for (j=i+1;j<n;j++)
{
cout << "(" << (c[i]*b[j]-b[i]*c[j])/(a[i]*b[j]-b[i]*a[j]) << "," << (c[i]*a[j]-a[i]*c[j])/(b[i]*a[j]-a[i]*b[j]) << ")" << endl;
}
}
return 0;
}
```
結果呈現:

##遞迴:河內塔
三根柱子(A、B、C),一開始有由大到小n個圓盤(1,2,3,4,5...n)在A上,求如何將所有移動到C。
大盤不得在小盤之上
一次只能移動一個
非移動中的盤子需在柱子上
輸入:n(n為不超過15的自然數)
```cpp=
#include <iostream>
using namespace std;
void f(int n,int a,int b)
{
char ch[3]={'A','B','C'};
int c=1;
for(int i=0;i<2;i++)
{
if (c==a||c==b)
c++;
}
if(n==1)
cout << "move ring" << n << " from " << ch[a-1] << " to " << ch[b-1] << endl;
else
{
f(n-1,a,c);
cout << "move ring" << n << " from " << ch[a-1] << " to " << ch[b-1] << endl;
f(n-1,c,b);
}
}
int main()
{
int in=0;
while (in>15||in<1)
{
cin >> in;
}
f(in,1,3);
return 0;
}
```
結果呈現:(6以上程序過於複雜,會超出畫面,便用5舉例)

解題重點:
1:要先用紙張輔助去想,如何用數學遞迴式表達每層的關係
2:了解子程式可以這樣用,來寫遞迴