# OOPS筆記 戴文凱教授
###### tags: 作者 蕭博文
---
comment
>this is comment[name=99shoes][time=Tue, Apr 13, 2021 8:22 PM][color=#4fe2c5]
# Ch.3 Function Basics
* IPO
* INPUT-PROCESS-OUTPUT[color=#4fe2c5] UML activity diagram may help
* cmath
* sqrt(4.0)、pow(2.0,3.0)、fabs(-7.5)、ceil(3.2)=4.0 、floor(3.2) = 3
* Extra 求0000 to 1111
```cpp=
///求0000-1111
int main()
{
for(int i=0;i<16;i++)
{
int tmp = i;
string s = "";
for(int j = 0;j<4;j++)
{
s = to_string(tmp%2)+s;
tmp>>=1;
}
cout<<s<<endl;
}
}
```
###### tags: 文翔
* arguments v.s. parameter 觀念
```cpp=
int main()
{
double price, bill;
int number;
cin>>number>>price;
bill = totalCost(number, price); ///this is called argument
}
double totalCoset(int numberParameter,double price Parameter) // this is called parameter
{
//不重要
}
```
* vector
* vector 在宣告時會有一內部capacity 先自行建立空間,直到你超過,vector的class會double空間 ps 肉眼看不到的。
* vector 初始化方式
* vector<int> name(3); 初始化3個空間
* vector<int> v = {4,5,16,8} v.push_back(25);
* vector 的印法
* (int n: vector)
{cout<<n<<endl;}
# Ch.4 Parameters and Overloading
* call by referenece v.s. call by pointer
* difference在於 pointer在Main function 將 address 當value 傳去其他function; reference 則是傳記憶體的參考值
```cpp=
void getNumbers(int* parameter1)//和tmp指向相同位置
{
*parameter1 = 20;
cout << parameter1 << endl;//0x00affc94{20}
cout << ¶meter1 << endl;//0x00affba8{0x00affc94{20}}
cout << *parameter1 << endl;//20
}
void showNumbers(int& parameter1)
{
parameter1 = 20;
cout << ¶meter1 << endl; // 0x00aff7c4{20}
cout << parameter1 << endl; //20
}
int main()
{
int x = 5;
int y = 5;
int* tmp = &x;//&x= 0x00affc94
cout << tmp << endl; // tmp = 0x00affc94{5}
cout << *tmp << endl; //*tmp = 5
cout << &tmp << endl; // &tmp = 0x00affc7c{0x00affc94{5}}
///由此可知tmp和&x指向相同的位置
getNumbers(tmp);
cout << &y << endl; // &y = 0x00aff7c4{5}
showNumbers(y);
}
```
# Ch.5 Arrays
* char page[30][100]; 在使用於function時 void DisplayPage(const char p [][100])
* vector的random[i] = random.at(i)
* vector二維 vector<vector<int>>v{va,vb,vc}
* vector二維push v.push_back(vector<int>());
* v[0].push_back(5);
---
# Ch.6 Structures and Classes
* **Structures** typically all members public, No member functions
* struct just has public way to save the data
* **Classes** typically all data members private, inteface member functions public
* class has public、procted、private way to save the variables
* structure解決array賦值的方法
```cpp=
struct Fruits
{
int apple;
int bananas;
int groups;
float tmp_;
int total_[3];
};
int main()
{
Fruits A{ 3,5,6,0,2,4,1.1 };
Fruits B;
cout << A.apple << " " << A.bananas << " " << A.groups << " " << A.tmp_ << endl;
for (int i = 0; i < 3; i++)
cout << A.total_[i] << " ";
cout << endl;
B = A;
cout << B.apple << " " << B.bananas << " " << B.groups << " " << B.tmp_ << endl;
for (int i = 0; i < 3; i++)
cout << B.total_[i] << " ";
cout << endl;
int a[10] = { 1 }; int b[10] = { 0 };
a=b /// 會出現false
}
//A和B的total分別輸出2 4 1
```
* Class 講解
```cpp=
class DayOfYear // class 為一抽象概念
{
public:
void input(); //public 的部分為interface 用於取private
void output();
private:
int month;
int day;
};
```
* Accessor v.s. Mutator are both called **Helper function**
* Accessor member functions, called get member functions, used **in reading data;**
* Mutator member functions, allowed object to **change data**
---
* Class 指標
```cpp=
class Box {
public:
Box(double L = 2.0, double b = 2.0, double h = 2.0)
{
length = L;
breath = b;
height = h;
}
double Volume()
{
return length * breath * height;
}
private:
double length;
double breath;
double height;
};
int main() {
Box Box1(3.3, 1.2, 1.5);//box1 addr 0x878e8a75
Box Box2(8.5, 6.0, 2.0);//box2 addr 0x00cffd94
Box* ptrBox;
ptrBox = &Box1;
cout << ptrBox->Volume() << endl;
cout << &ptrBox << " " << ptrBox << endl;//ptrBox 0x00cffd94 &ptrBox
cout << &ptrBox << " "; &ptrBox 0x005afd9c ptrBox 0x005afda8
ptrBox = &Box2;//&Box2 0X005afda8
cout << ptrBox->Volume() << endl;
}
```
# Ch.7 Constructors and Other Tools
* 有Constructor就不會有default值
* **Default** should always be defined.
```cpp=
class DayOfYear
{
public:
DayOfYear(int monthValue, int dayValue);//
DayOfYear();設一個default值
void input();
void output();
private:
int month;
int day;
void testDate(); //private 也可放function
}
//Way1
DayOfYear::DayOfYear(int monthValue,int dayValue)
{
month =monthValue;
day = dayValue;
}
//Way2
DayOfYear::DayOfYear(int monthValue,int dayValue)
:month(monthValue),day(dayValue){} // body left empty
//Way3 在body left 裡增加private裡的function testDate();
DayOfYear::DayOfYear(int monthValue,int dayValue)
:month(monthValue),day(dayValue)
{
testDate();
}
void DayOfYear::testDate()
{
...省
}
int main()
{
DayOfYear date1,date2;
date1(7,4);//可
date2.DayOfYear(5,5);//不可呼叫自己的建構子
date3 = DayOfYear(1,3); //可
}
```
* Inline Function
* Function 的執行會耗費很大的成本,用inline的話,cache會把程式搬過來,但花費很大的space,所以inline效率快占空間
* For class member functions:
* Place implementation(code)for function **IN** class definition
* For non-member functions:
* Use keyword inlne in function declaration and function heading
* 一般放在#include 的下方
* **inline** int f(int i ){return num+num}
* Macro like Inline function ch獨到鍵盤中最後一個字元
* Inline用compiler作處理 macro用 preprocessor作處理
```cpp=
#include<iostream>
using namespace std;
#define toupper(a)((a>='a'&&((a)<='z') ? ((a)-('a' - 'A')) : (a))
int main()
{
char ch;
printf_s("Enter a character分子:");
ch = toupper(getc(stdin)));
printf_s("%c", ch);
}
```
---
* Static members
* all objects of class **share one copy**
* One object changes it-all see changes
* Can show how many objects exist at given time
* 需在function外初始化
* Static functions
* 裡面不能放一般的private number 或class裡的其他function,只能放static members & static functions
```cpp=
#include<iostream>
using namespace std;
class Server
{
public:
static int getTurn();
static int ges();
int getter();
private:
static int turn;
int round;
};
int Server::turn = 0;//需在外面初始化靜態成員
int Server::getter()
{
round = 0;
round++;
cout << round << endl;
getTurn();
turn++;//可放於function中
return turn;
}
int Server::getTurn()
{
ges();//可放靜態function
//round++;//非靜態成員必須相對於特定物件
turn = 0;
turn++;
return turn;
}
int main()
{
Server m;
cout << m.getter();
cout << m.getTurn();//靜態成員函數可被物件呼叫
// Server::getter();///非靜態成員需有相對物件
Server::getTurn();
}
```
---
# Ch.8 OperatorOverloading
* Const
```cpp=
const Complex Complex::operator+(const Complex& a //這裡的const 是管a裡面的member)const //後面的const是使內部data
{
double first_, second_;
(a + 5).imaginaryValue;
first_ = realValue + a.realValue;
second_ = imaginaryValue + a.imaginaryValue;
return Complex(-first_ + second_, second_);
}
```
---
* Const*
* const int*p 指到一const 等同於 int const*p
* int* const p pointer指標本身是const =
* const int * const p ointer都不能改
```cpp=
int main()
{
///Normal 版
int a = 5;
int d = 5;
int* p = &a;
const int* b = &a; // 不能變動指到的位置的值,但不一定要指到a的位置
a = 4;
cout << &p << " " << *p;
*p = 6;
*b = 6;//不能改變
b=&d;
int* const f = &a;//可以變動指到位置的值,但不能變動指到的位置
*f = 8;
f = &d;//不能改變
const int* const g = b;//啥都不能改
}
```
---
* Operator () 、= 、[] must be overloaded as member function
*Friend function* is nto a member function but it can access private members
*ostream istream must be friend function
```cpp=
ostream& operator<<(ostream& outputStream, const Complex& a)
{
outputStream << a.realValue << " + " << a.imaginaryValue << "*" << "i" << endl;
return outputStream;
istream& operator>>(istream& inputStream, Complex&a//不能const)
{
string str;
getline(inputStream, str);
int x = str.find('=');
str.erase(str.begin(), str.begin() + x + 1);
char* copyStr;
const char* constc = nullptr;
constc = str.c_str();
double first_ = strtod(constc, ©Str);
copyStr += 2;
double second_ = strtod(copyStr, NULL);
a.realValue = first_;
a.imaginaryValue = second_;
return(inputStream);
}
```
* Prefix & Postfix
```cpp=
Prefix ++X has reference 須回傳一個物件也可以不加& , 回傳value
PrimeNumber& PrimeNumber:: operator++()
{
PrimeNumber os;
os.value = value;
if (os.value == 1)
{
os.value = 2;
value = 2;
return os;
}
int copy_value = value + 1;
bool isPrime = true;
for (; copy_value > 2; copy_value++)
{
for (int i = 2; i <= copy_value / 2; i++)
if (copy_value % i == 0)
{
isPrime = false;
break;
}
if (isPrime)
{
value = copy_value;
os.value = copy_value;
return os;
}
isPrime = true;
}
}
Postfix X-- //回傳value
PrimeNumber PrimeNumber:: operator--(int)
{
int transfer_Value = value;
if (value == 1)
return value;
if (value == 2)
{
value = 1;
return transfer_Value;
}
if (value == 3)
{
value = 2;
return transfer_Value;
}
int copy_value = value - 1;
bool isPrime = true;
for (; copy_value > 2; copy_value--)
{
for (int i = 2; i <= copy_value / 2; i++)
if (copy_value % i == 0)
{
isPrime = false;
break;
}
if (isPrime)
{
value = copy_value;
return transfer_Value;
}
isPrime = true;
}
}
```
---
* Rvalue 等號右邊 Lvalue等號左邊,要有一個位置
---
# Ch.9 String
```cpp=
int n;
string line;
cin>>n;
cin.get();//this can solve the problem below
getline(cin,line);
// if input is:42 &Hello hitchhiker , n set to 42,but line set to empty string!, 因為"\n" 停留在gteline()裡
```
# 題目練習 Fraction Numerator Denominator
```cpp=
void Fraction::getDouble()////化成小數形式輸出
{
double temp1 = ((double)numerator / (double)denominator);
int temp2 = numerator / denominator;
if (temp1 == temp2)///確認是否為整數
{
cout << temp1 << endl;
}
else
cout << fixed << setprecision(6) << temp1 << endl;///取小數後六位
cout.unsetf(ios::fixed);
}
void Fraction::outputReducedFraction()///化成分數形式輸出
{
int temp1 = numerator;
int temp2 = denominator;
if ((temp1 % temp2) == 0)/////如果為整數
{
cout << temp1 / temp2 << endl;
}
else
{///////////取最小分數
while (temp1 != 0 && temp2 != 0)
{
if (temp1 >= temp2)
temp1 = temp1 % temp2;
else
temp2 = temp2 % temp1;
}
if (temp1 > 0)
{
numerator /= temp1;
denominator /= temp1;
}
else
{
numerator /= temp2;
denominator /= temp2;
}
cout << numerator << "/" << denominator << endl;
}
}
```
---
* 輾轉相除法
```cpp=
int GCD(int input_1, int input_2)
{
if (input_2 == 0)
return input_1;
return GCD(input_2, input_1 % input_2);
}
```
---
* 九宮格算法
```cpp=
#include<iostream>
using namespace std;
#include<sstream>
#include<vector>
int main()
{
stringstream input_;
string input_1;
int** p = new int* [9];
for (int i = 0; i < 9; i++)
{
p[i] = new int[9];
}
while (true) {
int i = 0;
while (getline(cin, input_1) && i < 9)
{
int k = 0;
for (int j = 0; j < input_1.size(); j++)
if (input_1[j] <= '9' && input_1[j] >= '0')
{
input_ << input_1[j];
input_ >> p[i][k];
k++;
input_.str("");
input_.clear();
}
i++;
}
if (i != 9) break;
////determine
//for (int X = 0; X < 3; ++X) {
// for (int Y = 0; Y < 3; ++Y) {
// for (int x = 0; x < 3; ++x) {
// for (int y = 0; y < 3; ++y) {
// p[X * 3 + x][Y * 3 + y] = 0;
// }
// }
// }
//}
//i % 3 = X;
//i / 3 = Y
bool de[9] = { false };
bool decision = true;
for (int i = 0; i < 9; ++i) {
for (int j = 0; j < 9; ++j) {
de[p[(i % 3) * 3 + j % 3][(i / 3) * 3 + j / 3] - 1] = true;
}
for (int k = 0; k < 9; ++k)
if (de[k] == false)
{
cout << "False" << endl;
decision = false;
break;
}
}
bool de3[9] = { false };
if (!decision)continue;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
de3[p[i][j] - 1] = true;
for (int k = 0; k < 9; ++k)
if (de3[k] == false)
{
cout << "False" << endl;
decision = false;
break;
}
}
bool de2[9] = { false };
if (!decision)continue;
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
de2[p[j][i] - 1] = true;
for (int k = 0; k < 9; ++k)
if (de2[k] == false)
{
cout << "False" << endl;
decision = false;
break;
}
}
cout << "True" << endl;
}
}
```
* 檔案輸出入教學
```cpp=
#include<iostream>
#include<fstream>
using namespace std;
#include<vector>
void arrangement(vector<int>& a, vector<int>& b)////將a輸入並排列,算好每個值的個數並放入b裡面
{
/////////bubble sort
int length_ = a.size();
while (length_ > 1) {
length_--;
for (int i = 0; i < length_; i++) {
// 如果前面的元素比後面的元素要大,則交換元素位置
if (a[i] > a[i + 1]) {
int tempValue = a[i];
a[i] = a[i + 1];
a[i + 1] = tempValue;
}
}
}
int count_ = 1;
/////////將值和值的個數分別push進b陣列裡
for (int i = 0; i < a.size() - 1; i++)
{
if (a[i] == a[i + 1])
count_++;
else
{
b.push_back(a[i]);
b.push_back(count_);
count_ = 1;
}
}
/////如果算到最後都一樣
if (a[a.size() - 1] == a[a.size() - 2])
{
b.push_back(a[a.size() - 1]);
b.push_back(count_);
}
if (a[a.size() - 1] != a[a.size() - 2])
{
b.push_back(a[a.size() - 1]);
b.push_back(count_);
}
}
int main()
{
//////讀檔
ifstream fin("grade.txt");
if (!fin)
{
cout << "檔案無法開啟\n";
return 1;
}
vector<int>box_;
vector<int>boxTemp_;
int input_;
while (fin >> input_)
{
box_.push_back(input_);
}
///讀檔結束
fin.close();
arrangement(box_, boxTemp_);
/////寫檔
ofstream fout("grades.Output");
int c[6] = { 0,1,2,3,4,5 };
int count_2 = 1;
for (int i = 0; i < 6; i++)
{
if (c[i] != boxTemp_[count_2 - 1])
fout << "0 grade(s) of " << i << endl;
else
{
fout << boxTemp_[count_2] << " grade(s) of " << boxTemp_[count_2 - 1] << endl;
count_2 += 2;
}
}
fout.close();
//寫檔結束
}
```
---
# Strfind
```cpp=
#include<iostream>
#include<string>
using namespace std;
int main()
{
string str("Please, replace the vowels in this sentence by asterisks.");
size_t found = str.find_first_of("aeiou", 6);
while (found != string::npos)
{
cout << found << str[found] << endl;
str[found] = '*';
found = str.find_first_of("aeiou", found + 1);
}
cout << str << endl;
}
```
---
# 檔案輸出入進階
```cpp=
#include<iostream>
#include<fstream>
using namespace std;
#include<string>
#include<sstream>
int main()
{
string input_;
cin >> input_;
ifstream fin(input_);
stringstream ss;
if (!fin)
cout << "can't open";
else
{
while (getline(fin, input_))
{
int first;
string second;
double third;
ss << input_;
cout << ss.str() << endl;
ss.str("1\n2\n3\n4\n5\n");
cout << ss.str();
ss >> first >> second >> third;
cout << first << " " << second << " " << third << endl;
string fourth;
fourth = to_string(first);
fourth.empty() ? cout << "empty\n" : cout << fourth << endl;
second += "4";
cout << second << endl;
ss.str("");
ss.clear();
}
}
fin.close();
}
```
# 神奇演算法 海岸線
```cpp=
#include <iostream>
#include<vector>
using namespace std;
class point {
public:
int x, y;
point() { x = 0; y = 0; }
point(int x_, int y_) {
x = x_;
y = y_;
}
};
class Node {
public:
point p;
Node* next;
Node() {
p.x = 0;
p.y = 0;
next = NULL;
}
Node(point p_) {
p.x = p_.x;
p.y = p_.y;
next = NULL;
}
};
bool smaller(int a1, int c1, int a2, int c2) {
return a1 < a2 || (a1 == a2 && c1 < c2);
}
void Sort(vector<int>& area, vector<int>& coast) {
for (int i = 0; i < area.size() - 1; ++i) {
for (int j = 1; j < area.size() - i; ++j) {
if (smaller(area[j - 1], coast[j - 1], area[j], coast[j])) {
swap(area[j - 1], area[j]);
swap(coast[j - 1], coast[j]);
}
}
}
}
int main() {
int w, h;
cin >> h >> w;
bool** map, ** map2;
map = new bool* [w + 2];
map2 = new bool* [w + 2];
for (int i = 0; i < w + 2; ++i) {
map[i] = new bool[h + 2]{ 0 };
map2[i] = new bool[h + 2]{ 0 };
}
for (int y = 0; y < h; ++y) {
for (int x = 0; x < w; ++x) {
char c;
cin >> c;
map[x + 1][y + 1] = (c == '#');
map2[x + 1][y + 1] = map[x + 1][y + 1];
}
}
vector<int> Areas, Coasts;
int mx[4]{ 0,0,-1,1 }, my[4]{ -1,1,0,0 };
for (int y = 1; y < h + 1; ++y) {
for (int x = 1; x < w + 1; ++x) {
if (map2[x][y]) { //island
Node* head = new Node(point(x, y)), * rear = head;
Node* flag = head;
map2[flag->p.x][flag->p.y] = 0;
while (flag != NULL) {
for (int i = 0; i < 4; ++i) {
if (map2[flag->p.x + mx[i]][flag->p.y + my[i]]) {
Node* newnode = new Node(point(flag->p.x + mx[i], flag->p.y + my[i]));
map2[flag->p.x + mx[i]][flag->p.y + my[i]] = 0;
rear->next = newnode;
rear = rear->next;
}
}
flag = flag->next;
}
for (int y = 1; y < h + 1; ++y) {
for (int x = 1; x < w + 1; ++x) {
cout << map2[x][y];
}
cout << endl;
}
int area = 0, coast = 0;
while (head != NULL) {
area++;
for (int i = 0; i < 4; ++i) {
if (map[head->p.x + mx[i]][head->p.y + my[i]]) {
coast--;
}
}
Node* tmp = head;
head = head->next;
delete tmp;
}
coast += (area << 2);
Areas.push_back(area);
Coasts.push_back(coast);
}
}
}
//sorting
Sort(Areas, Coasts);
for (int i = 0; i < Areas.size(); ++i) {
cout << Areas[i] << " " << Coasts[i] << endl;
}
}
```
# 海岸線地回版
```cpp=
#include<iostream>
using namespace std;
#include<vector>
#include<cmath>
int main()
{
int w, h;
int total = 0;
vector<int> resultX, vector<int> resultY;
for (int i = 0; i < resultX.size(); ++i) {
for (int dir = 0; dir < 4; ++dir) {
total += 4;
if (map[resultX[i] + mx[dir]][resultY[i] + my[dir]] == 1) total--;
}
}
}
int mx[4]{ 0,0,-1,1 }, my[4]{ -1,1,0,0 };
void Search(vector<int>& resultX, vector<int>& resultY, bool** map, int w, int h, int x, int y) {
map[x][y] = 0;
resultX.push_back(x);
resultY.push_back(y);
for (int i = 0; i < 4; ++i) if (map[x + mx[i]][y + my[i]] == 1) Search(resultX, resultY, map, w, h, x + mx[i], y + my[i]);//up
if (map[x][y - 1] == 1) Search(resultX, resultY, map, w, h, x, y - 1);//up i==0
if (map[x][y + 1] == 1) Search(resultX, resultY, map, w, h, x, y + 1);//up
if (map[x + 1][y] == 1) Search(resultX, resultY, map, w, h, x + 1, y);//up
if (map[x - 1][y] == 1) Search(resultX, resultY, map, w, h, x - 1, y);//up
}
```
# NumberGame
```cpp=
#include"NumberGame.h"
void NumberGame::SetInput(int input)// : set the given integer A.
{
input_ = input;
}
void NumberGame::ProcessInput()// : splitting the integer A into several digits.
{
int a;
while (input_ > 0)
{
a = input_ % 10;
/* if (a == 5)
factor[0]++;
else if (a == 7)
factor[1]++;
else*/
processInput_.push_back(a);
input_ /= 10;
}
}
void NumberGame::SetFileName(string input_)//: set the file name of the file where list S is located.
{
fileInput_ = input_;
}
void NumberGame::LoadNumberList()// : read list S from the file.
{
int a;
ifstream fin(fileInput_);
if (!fin)
cout << "檔案無法開啟" << endl;
else
{
while (!fin.eof())
{
fin >> a;
listS.push_back(a);
}
fin.close();
}
}
void NumberGame::PrintAllValid() //: print all the valid numbers in S ascendingly
{
//vector<int>corresponded;///放入符合的資料
sort(processInput_.begin(), processInput_.end());
bool whether_0 = false;
while (processInput_[0] == 0)//將0刪除
{
whether_0 = true;
processInput_.erase(processInput_.begin());
}
bool divide = false;
bool pass_ = false;
bool whether_1 = false;//用來判斷是否有1
vector<int>repeat;//儲存重複index
vector<int>corresponeded;//儲存符合的資料
while (processInput_.size() > 0 && processInput_[0] == 1)
{
whether_1 = true;
processInput_.erase(processInput_.begin());
}
/////////////////////////////////////
bool retmp = false;
int tmp = 0;
int count_ = 0;
int cotmp = processInput_.size(); //point 因為processinput_.size()==0時會進入以下的for迴圈,所以用cotmp來代替
for (int i = 0; i < cotmp - 1; i++)//用來記錄ProcessInput裡是否有重複的
{
int j = i;
while (j != processInput_.size() - 1 && processInput_[j] == processInput_[j++])//儲存數字 //重複的個數
{
tmp = processInput_[j];
count_++;
retmp = true;
}
if (processInput_.size() - 1 >= j && tmp == processInput_[j - 1])
count_++;
if (retmp)
{
repeat.push_back(tmp);//儲存重複的數字
repeat.push_back(count_);///重複個數
retmp = false;
i += count_ - 1;
count_ = 0;
}
}
for (int i = 0; i < listS.size(); ++i) {
int val = listS[i];
if (whether_1 && val == 1) ///判斷List裡是否有1或0
{
corresponeded.push_back(val);
continue;
}
if (whether_0 && val == 0)
{
corresponeded.push_back(val);
continue;
}
if (val % 2 != 0 && val % 3 != 0 && val % 7 != 0 && val % 5 != 0)//代表是其他質數
continue;
for (int k = cotmp - 1; k > cotmp / 2; k--)//做n*n/2次迴圈
{
int tmp = val;
for (int m = k; m >= 0; m--)
{
if (tmp % processInput_[m] == 0)
{
tmp /= processInput_[m];
divide = true;
}
else//來確定這個數字是否有重複的可能性,節省之後跑回圈的次數
{
divide = false;
if (repeat.size() > 0)
{
for (int k = 0; k < repeat.size(); k += 2)
if (processInput_[m] == repeat[k])
{
continue;
m += repeat[k + 1];
}
}
}
if (tmp == 1 && divide)//如果tmp是1且divide成立就輸出
{
corresponeded.push_back(listS[i]);
pass_ = true;
break;
}
}
if (pass_)
{
pass_ = false;
break;
}
}
}
sort(corresponeded.begin(), corresponeded.end());
for (int i = 0; i < corresponeded.size(); i++)
cout << corresponeded[i] << endl;
}
void NumberGame::Reset() ///: reset all variables.
{
listS.clear();
processInput_.clear();
}
```
# Ch11 Separate complication and namespaces
#### Encapsulation rules
- 成員變數為private,由成員函數(public)存取
#### Interface in header file 定義,Implementation in .cpp file 實作
#### NameSpace

- main function 含多個namespace時要用block區分
####unNameNamespace只能用於internal linkage(同屬一個.cpp)
e.g. 像是我定義一個nameSpace latTop , latTop裡分別有user and passWord 而且 user and passWord裡面分別有一個invalid()做判斷,這時要用unNameNamespace去寫Invalid()。ps: user and password分別在不同.cpp
unnameNamespace裏頭定義的variable像是全域變數,但只能給特定的.cpp使用

#### 如果沒有第16行,void h()裡面讀不到j,如果有16行則void h()裡面的i無法辨別,所以可將j指定A::j解決問題。
# Ch12 Streams and File I/O
## Streams在此強調不只是螢幕輸入,來源可能有很多種,以下則是我們目前學到的
##### Input stream - from file or keyboard
##### Output stream go to screen or file
``` cpp=
#include<fstream>
using namespace std;
ifstream inStream;
ofstream outStream;
inStream.open("infile.txt");
int oneNumber,anotherNumber;
inStream>>oneNumber>>anotherNumber;
outStream.open("outfile.txt");
outStream<<"oneNumber="<<oneNumber<<"anotherNumber="<<anotherNumber;
```
#### Flush 將暫存在buffer的輸入寫入檔案
```cpp=
#include <ostream> // std::flush
#include <fstream> // std::ofstream
int main() {
std::ofstream outfile("test.txt");
for (int n = 0; n < 100; n++)
outfile << n << std::flush;
outfile.close();
return 0;
}
```
#### Check whether file is fail
```cpp=
inStream.open("stuff.txt");
if(inStream.fail())
{
cout<<XXXX\n;
exit(1);
}
```
#### Check End of file
只能get char 型態 ,輸入atoi,輸出a i
```cpp=
int main()
{
ifstream inStream;
char next;
inStream.open("stuff.txt");
inStream.get(next); //GET a
char op;
while (!inStream.eof())//單純只是讀並沒有inputt
{
cout << next;//如果沒有以下兩行則一直讀到a
inStream >> op;//t//有Input
inStream.get(next);//o//有input
}
使用while(!instream.eof())
{
不管是inStream>>next
或是inStream.get(next)
輸出皆會是atoii
}
但如果是以while(inStream>>next)
或是while(inStream.get(next))
會輸出atoi
所以.eof有buffer的問題
}
```
#### Formatting
cout.width(5)=cout<<setw(5)都只能影響下一個輸出
cout.precision(5)=cout<<setPrecision(5)//設定輸出個數,接只能影響下一個
cout.setf(ios::fixed)= setiosflags(ios::fixed);//設定小數個數
```cpp=
double s = 20.7843909
/*cout<<setprecision(2)<<s<<endl;//输出21
cout<<fixed<<s<<endl;//输出20.78*/
/*cout<<setprecision(2)<<s<<endl;//输出21
cout<<showpoint<<s<<endl;//输出21.(有个点)*/
/* cout<<fixed<<s<<endl;//输出20.784391
cout<<showpoint<<s<<endl;//输出20.784391*/
/*cout<<setprecision(2)<<s<<endl;//输出21
cout<<showpoint<<s<<endl;//21.(有个点)
cout<<fixed<<s<<endl;//20.78*/
```
#### Saving Flag settings
在此判斷OutStream會將上次的回傳位置傳給這次的所以判斷是延遲,但輸出正常
在此如果將第20行拿掉 會輸出0 30 60 90
將第21行拿掉0.000000 30.141593 60.283185 90.424778
``` cpp=
#include <ostream> // std::flush
#include <fstream> // std::ofstream
#include<istream>
#include<iostream>
#include<iomanip>
#include<vector>
const double PI = 30.141592653;
using namespace std;
void outputStuff(ofstream& outStream)
{
int precisionSetting = outStream.precision(); // = 6
long flagSettings = outStream.flags();// // flagSettings = 513
outStream.setf(ios::fixed | ios::showpoint);
int a = outStream.precision(3);//a=6
for (int n = 0; n < 4; n++)
outStream << PI * n << std::flush << endl;
a = outStream.precision(2);//a=3
for (int n = 0; n < 4; n++)
outStream << PI * n << std::flush << endl;
int b = outStream.precision(precisionSetting);//b =2
int c = outStream.flags(flagSettings);//c= 8721
for (int n = 0; n < 4; n++)
outStream << PI * n << std::flush << endl;
cout << setprecision(2) << PI;
}
```

stringstream教學

``` cpp=
#include<iostream>
#include<sstream>
int main()
{
string b = "holy Bible\n";
istringstream in(b);
string word1, word2, word3, word4;
in >> word1;
in.seekg(3);//去指定字串位置找字串,空白停止 e.g.in.seekg(3) 輸出y in.seek(6)ible
in >> word2;
cout << word1 << " " << word2 << endl; // //word1 = holy word2 = y
in >> word3;
cout << word3 << " ";word3 = Bible // 如果是seekg(5)則會變成 word2 = Bible word3 = ""
in >> word4;
cout << word4 << " ";word4 = ""
}
```
# Chap13 Recursion
### Point
- 不要寫成無限遞迴
-終止條件須回傳正確值
-遞迴須回傳正確值
-確認大問題能拆解成相同的小問題
### 確認是否為prime
```cpp=
bool isPrime(int p,int i =2)
{
if(i==p)return 1;
if(p%i==0) return 0;
return isPrime(p,i+1);
}
```
### 確認是否為GCD最大公因數 在此m>n
```cpp=
int GCD(int m, int n)
{
if ((m % n) == 0)return n;
return GCD(n, m % n);
}
```
### 認是基數個1還是偶數個
```cpp=
bool oddNumberOfOnes(string s);
bool evenNumberOfOnes(string s)
{
if (s.length() == 0)
return true;
else if (s[0] == '1')
return oddNumberOfOnes(s.substr(1));
else
return evenNumberOfOnes(s.substr(1));
}
bool oddNumberOfOnes(string s)
{
if (s.length() == 0)return false;
else if (s[0] == '1')return evenNumberOfOnes(s.substr(1));
else return oddNumberOfOnes(s.substr(1));
}
```
### Tail Recursion
-more efficient
-差異在於有沒有將回傳值用一個變數做儲存
not tail

tail

# Chap 14 Inheritance
#### 兒子繼承父親只需定義自己的FUNCTION,其他的FUNCTION用public繼承父親的,要寫父親的get 或setfunction去拿private資料
-Parent clss refer to base class
-Child class refer to derived class
-一個class可繼承多個class,但不能父子互相繼承
## FUNCTION SIGNATURE
int Divide(int n, int m);
double Divide(int n, int m);
Constructor 和default Constructor不能繼承 只能以下面的方式
在此的CreatureDemoPinky會先呼叫CreatureDemo再呼叫Creature
```cpp=
#include<iostream>
using namespace std;
class Creature
{
public:
Creature();
Creature(int newType, int newStrength, int newHIt);
private:
int newType;
int newStrength;
int newHIt;
};
Creature::Creature() :newType(0), newStrength(0), newHIt(0) {}
Creature::Creature(int newType, int newStrength, int newHit) : newType(newType), newStrength(newStrength), newHIt(newHit) {}
class CreatureDemon :public Creature
{
private:
int height;
public:
CreatureDemon() :Creature(), height(0) {}
CreatureDemon(int newType, int newstrength, int hit, int height) :Creature(newType, newstrength, hit), height(height) {}
};
class CreatureDemonPinky :public CreatureDemon
{
private:
int Criticalstrike;
public:
CreatureDemonPinky() :CreatureDemon(), Criticalstrike(0) {}
CreatureDemonPinky(int newType, int newstrength, int hit, int height, int Criti) :CreatureDemon(newType, newstrength, hit, height), Criticalstrike(Criti) {}
};
int main()
{
return 0;
}
```
#### IS a v.s. Has a relationships
-Inhertiance 敞篷車 is a 汽車
-Onc class has another class member data
#### Default compiler provide three defaults:
-Default(parameterless)Constructor
-Copy Constructor
-Assignment operator
# Chap 15 Polymorphism and Virtual Functions
## Late Biding(Dynamic binding) 、Virtual functions
### Meaning
#### Early binding 的 early 指的就是編譯的這個時間點(因為相較於執行發生較早)發生的binding,late 指的就是 run time 時發生的 binding。一般而言在編譯過程中 compiler 會去查找函數定義來進行鏈結,因此基本上預設所有 function call 都是透過 early binding(static binding)完成的。
#### virtual function 就是在 class member function 宣告前加上關鍵字 "virtual" 告訴編譯器這個 function 之後會被 overridden 所以要採用 "late binding",而 virtual function 可以實現讓同一個 function 根據不同種類的 object 而有不同的行為(函數定義),因此可以視為一種多型(Polymorphism)的方式。
1. 一個 class 中的 virtual function 在所有繼承它的子類別中自動預設此 function 為 virtual。
2. 一個沒有函數定義的 virtual function 稱做 "pure virtual function",ex: virtual void height() = 0;
3. 包含至少一個 pure virtual function 的 class 稱為 "Abstract class",Abstract class 是不能生成 object 的,只能拿來當作父類別被繼承。
4. 繼承 Abstract class 的子類別必須 override pure virtual function,否則也會變成一個 Abstract class。
預設中所有的 function call 都是採用 "early binding" 的方式進行鏈結,顯然我們必須要有某個語法來告訴編譯器先不要做binding,再拖一下,這個keyword就是 "virtual" 拉!
```cpp =
using namespace std;
#include <iostream>
using namespace std;
class Homo
{
public:
virtual void height()
{
cout << "Homo height is unlimited" << endl;
}
};
class neanderthalensis : public Homo
{
public:
void height()
{
cout << "neanderthalensis is about 1.5 meters tall" << endl;
}
};
int main()
{
Homo* h;
neanderthalensis n;
h = &n;
// early binding
h->height();
return 0;
}
```
#### Overrdidden v.s. redefined
Virtual funciton definition changed in a derived class is called overridden
Non-virtual functions changed are called redefined
另外使用virtual functions 會耗費較大的記憶體且執行速度較慢(late binding)
### Example of abstract class
```cpp=
class Base
{
public:
virtual void show()=0;
//pure virtual funciton
};
class Derived:public Base
{
public:
void show()
{
cout<<"Implementation of Virtual function in derived class";
}
};
```
#### Object slicing
Happens when a derived class object is assigned to a base class object, additional attributes of a derived class object are sliced off to form the base class object.
```cpp=
class BaseCls {
private:
string name;
public:
BaseCls(const string& s) :name(s) {}
virtual void show()const {
cout << "Base: " << name << "Show()" << endl;
}
};
class DerivedCls :public BaseCls {
private:
string name;
string habitat;
public:
DerivedCls(const string& sp, const string& s, const string& h) :BaseCls(sp), name(s), habitat(h) {};
virtual void show()const {
cout << "DerivedCls:" << name << "Show()in" << habitat << endl;
}
};
void Fun1(BaseCls a) { a.show(); }
void Fun(const BaseCls& a) { a.show(); }
int main()
{
BaseCls ocBase("Base");
DerivedCls ocDerived("Test", "TEST1", "test1&test2");
cout << "pass-by-value" << endl;
Fun1(ocBase);
Fun1(ocDerived); // 在此的derived 傳給BaseCls a的時候會被蓋掉,變成BaseCls
cout << "pass by reference" << endl;
Fun(ocBase);
Fun(ocDerived);//用reference則不會
return 0;
}
```
#### Pure virtual destructor要實作,不像一般的pure virtual
執行順序是先呼叫自己的再呼叫祖先的
```cpp=
class BaseCls {
private:
public:
virtual~BaseCls() = 0;
virtual void show()const {
cout << "Base: " << "Show()" << endl;
}
};
BaseCls::~BaseCls() { cout << "hi" << endl; }
class DerivedCls :public BaseCls {
private:
int* m_pnArry;
public:
virtual ~DerivedCls() {
cout << "Derived\n";
delete[]m_pnArry;
}
DerivedCls(int nLength) { m_pnArry = new int[nLength]; }
};
int main()
{
DerivedCls* pDerived = new DerivedCls(5);
BaseCls* pBase = pDerived;
delete pBase;
return 0;
}
```
# Ch16 templates
#### First line called"template prefix", tells complier what's coming is "template" and that T is a type parameter
#### 如果有寫到pointer , destructor必須要寫好
```cpp=
template<class T>
void swapValues(T& var1, T& var2)
{
T temp;
temp = var1;
var1 = var2;
var2 = temp;
}
```
#### 如果要傳入兩個不同型態引述需要兩個class T
```cpp=
template<class T, class T2>
void swapValues(T& var1, T2& var2)
{
T temp;
temp = var1;
var1 = var2;
var2 = temp;
}
int main()
{
int a = 5;
double b = 5.5;
swapValues(a, b);
cout << b << " " << a;
}
```
#### Class Template



#### Non-template parameter
```cpp=
template<int N>struct S { int a[N]; };
//*pf pointer to function // (S<10>::*a)[10] pointer to member object(of type int[10])
template<char c, int(&ra)[5], int(*pf)(int), int(S<10>::* a)[10] >struct Complicated { void foo(char base) { ra[4] = pf(c - base); } };
int a[5];
int f(int n) { return n; }
int main()
{
S<10>s;
s.a[9] = 4;
Complicated<'2', a, f, &S<10>::a>c;//int (&S<10>::*)[10]長這樣
c.foo('0');
cout << s.a[9] << a[4] << endl;
}
```
## 很酷的寫法 for_each為template底下的
```cpp=
template<class InputIt, class unaryfunction>
unaryfunction for_each(InputIt first, InputIt last, unaryfunction f)
{
for (; first != last; ++first)f(*first);
return f;
}
int main()
{
vector<int>nums{ 3,4,2,8,15,267 };
auto print = [](const int& n)
{
cout << " " << n;
};
cout << "before\n";
for_each(nums.begin(), nums.end(), print);
cout << '\n';
for_each(nums.begin(), nums.end(), [](int& n) {n++; });
for_each(nums.begin(), nums.end(), print);
}
```
# Ch18 Exception Handling
#### Try-Throw-Catch
#### Exceptions must be "handle" in some catch block

## 可以重複執行的CODE
在執行Quotient的時候發現分母為0,先去class裡面將錯誤訊息放入,再跑回呼叫他的function,接下來執行main裡面的catch並輸出,接者依然能重複執行
```cpp=
#include <iostream>
using std::cout;
using std::cin;
using std::endl;
#include <exception>
using std::exception;
// 定義一個例外類別:DivideByZeroException
// 當發生除0錯誤時可丟出此類例外
class DivideByZeroException : public exception {
public:
// 建構子:直接實作,指定錯誤訊息
DivideByZeroException() : exception("attempted to divide by zero") {}
};
double quotient(int numerator, int denominator)
{
// 假如除數為0丟出 DivideByZeroException 例外並結束此函式
if (denominator == 0)
throw DivideByZeroException(); //丟出例外並結束函式執行//
// 傳回除法運算結果
return static_cast<double>(numerator) / denominator;
} // end function quo
int main()
{
int number1; // 使用者指定的被除數
int number2; // 使用者指定的除數
double result; // 除法運算結果
cout << "Enter two integers (end-of-file to end): ";
while (cin >> number1 >> number2) {
// try區塊內含可能傳回例外的程式碼
// 以及當例外發生時不應執行的程式碼
try {
result = quotient(number1, number2);
cout << "The quotient is: " << result << endl;
} // end try
// 例外處理程式:處理除0例外
catch (DivideByZeroException& divideByZeroException)
{
cout << "Exception occurred: "
<< divideByZeroException.what() << endl;
} // end catch
cout << "\nEnter two integers (end-of-file to end): ";
} // end while
cout << endl;
return 0; // 正常結束
}
```
## 函式裡面放try throw catch
先執行main裡的try在執行function throwException 接者try throw catch 在function 最後的throw 則由main裡的 catch接到
```cpp=
#include <iostream>
using std::cout;
using std::endl;
#include <exception>
using namespace std;//using std::exception;
// throw, catch and rethrow exception
void throwException()
{
// 丟出例外並利用catch捉住例外
try {
cout << " Function throwException throws an exception\n";
throw exception(); // 產生例外
} // end try
// 處理例外
catch (exception& caughtException) {
cout << " Exception handled in function throwException"
<< "\n Function throwException rethrows exception";
throw; // 重新丟出例外
} // end catch
cout << "This also should not print\n";
} // end function throwException
int main()
{
// 丟出例外
try {
cout << "\nmain invokes function throwException\n";
throwException();
cout << "This should not print\n";
} // end try
// 處理例外
catch (exception& caughtException) {
cout << "\n\nException handled in main\n";
} // end catch
cout << "Program control continues after catch in main\n";
return 0;
} // end main
```
# Ch19 Design Pattern
## Singleton MVC
#### Data(model)- student-acting as a model
#### interface(view)- studentview-print student details on console
#### operation(controller)- studentcontroller(做邏輯運算CRUD)- responsible to stroe data in student object and update view studentview accordingly
## sequence diagram 個模組間的操作順序,通常只整個系統
e.g. Online shop interface->Item list-> purchase interface
## Activity diagram
e.g.要了解使用者的需求,通常只使用者流程
## 流程圖->某一個function或程式碼的流程
## 先從activity diagram ->sequence diagram -> flow chart
## 流程圖工具 googl draw.io、 microsoft project、visual paradiam
has a-> composition 你泥中有我我泥中有你