---
# System prepended metadata

title: OOPS筆記 戴文凱教授

---

#    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 << &parameter1 << endl;//0x00affba8{0x00affc94{20}}
	cout << *parameter1 << endl;//20
}
void showNumbers(int& parameter1)
{
	parameter1 = 20;
	cout << &parameter1 << 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, &copyStr);
	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
![](https://i.imgur.com/DQKBgJv.png)
- 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使用
![](https://i.imgur.com/JkAkXrR.png)

#### 如果沒有第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;
}
```
![](https://i.imgur.com/wVGvOv5.png)


stringstream教學
![](https://i.imgur.com/oGRfRyD.png)

``` 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
![](https://i.imgur.com/xod4U6C.png)

tail
![](https://i.imgur.com/Ov9nwVb.png)

# 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;
}

```
#### ＩS 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

![](https://i.imgur.com/iidjvSj.png)
![](https://i.imgur.com/hHHTZzc.png)
![](https://i.imgur.com/Qh08T9Q.png)

#### 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

![](https://i.imgur.com/kaCYUiX.png)

## 可以重複執行的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 你泥中有我我泥中有你


