# 高斯消去 > 所有分母為 0 的輸入都會強制轉換成分母為 1 > 目前只能計算只有一組解的線性方程 > 分數「y分之x」以「x/y」表示 (例如:2分之3 -> 3/2) ## Main ```cpp= #include <iostream> #include "ELEMENT.h" using namespace std; //output matrix template<class T>void print(string str, T *arr, const unsigned& sz); template<class T>void print(string str, T **arr, const unsigned& _i, const unsigned& _j); template<class T>void print(string str, T ***arr, const unsigned& _i, const unsigned& _j, const unsigned& _k); class Gaussian_Elimination { private: unsigned D; //矩陣大小(以係數方陣為主) Element*** CP; //紀錄矩陣在消去時的過程 Element** matrix; //矩陣內容 Element* r; //線性方程之根 public: inline void New_All(); //宣告陣列大小 inline void Delete_All(); //移除陣列 inline void Input(); //輸入 inline void Update_CP(const int& k); //更新目前的計算過程 inline void Elimination(); //高斯消去 inline void Get_Roots(); //取得線性方程之根 inline void Solve(); //類 int main() }; //--------------------------- Main --------------------------- int main() { Gaussian_Elimination GE; GE.Solve(); return 0; } // --------------------------- class Gaussian_Elimination --------------------------- inline void Gaussian_Elimination::New_All() { CP = new Element * *[D] {0}; matrix = new Element * [D]; r = new Element[D]; for (unsigned i = 0; i < D; i++) { CP[i] = new Element * [D + 1]{ 0 }; matrix[i] = new Element[D + 1]; for (unsigned j = 0; j < D + 1; j++) { CP[i][j] = new Element[D - 1]{ 0 }; } } } inline void Gaussian_Elimination::Delete_All() { for (unsigned i = 0; i < D; i++) { for (unsigned j = 0; j < D + 1; j++) { delete[] CP[i][j]; } delete[] CP[i]; delete[] matrix[i]; } delete[] CP; delete[] matrix; delete[] r; } inline void Gaussian_Elimination::Input() { cout << "Input the size of Coefficient Matrix:\n"; cin >> D; cout << "Input your Augmented Matrix:\n"; New_All(); for (unsigned i = 0; i < D; i++) { for (unsigned j = 0; j < D + 1; j++) { cin >> matrix[i][j]; } } } inline void Gaussian_Elimination::Update_CP(const int& k) { for (unsigned i = 0; i < D; i++) { for (unsigned j = 0; j < D + 1; j++) { CP[i][j][k] = matrix[i][j]; } } } inline void Gaussian_Elimination::Elimination() { for (unsigned R = 0; R < D - 1; R++) { for (unsigned i = R + 1; i < D; i++) { Element A = matrix[i][R], B = matrix[R][R], C; C = A / B; for (unsigned j = R; j < D + 1; j++) { Element T = matrix[R][j]; matrix[i][j] = matrix[i][j] - T * C; } } Update_CP(R); } } inline void Gaussian_Elimination::Get_Roots() { for (int i = int(D) - 1; i >= 0; i--) { Element tmp = matrix[i][D]; for (int j = int(D) - 1; j > i; j--) { tmp = tmp - r[j] * matrix[i][j]; } r[i] = tmp / matrix[i][i]; } } inline void Gaussian_Elimination::Solve() { Input(); Elimination(); print("\nCalculation:", matrix, D, D + 1); Get_Roots(); print("\nRoots:", r, D); print("\nComputational Process:", CP, D, D + 1, D - 1); Delete_All(); } template<class T> void print(string str, T *arr, const unsigned& sz) { cout << str << '\n'; for (unsigned i = 0; i < sz; i++) { cout << arr[i] << " "; } cout << '\n'; } template<class T> void print(string str, T **arr, const unsigned& _i, const unsigned& _j) { cout << str << '\n'; for (unsigned i = 0; i < _i; i++) { for (unsigned j = 0; j < _j; j++) { cout << arr[i][j] << " "; } cout << '\n'; } } template<class T> void print(string str, T ***arr, const unsigned& _i, const unsigned& _j, const unsigned& _k) { cout << str << '\n'; for (unsigned k = 0; k < _k; k++) { cout << '\n'; for (unsigned i = 0; i < _i; i++) { for (unsigned j = 0; j < _j; j++) { cout << arr[i][j][k] << " "; } cout << '\n'; } } } ``` ## "ELEMENT.h" ```cpp= //ELEMENT.h #ifdef ELEMENT #define ELEMENT __declspec(dllexport) #else #define ELEMENT __declspec(dllimport) #endif #include <iostream> #include <algorithm> using namespace std; class ELEMENT Element{ public: Element(): numerator(0), denominator(1), interger(true){} Element(const int &X): numerator(X), denominator(1), interger(true){} Element(const int &X, const int &Y): numerator(X), denominator(Y){ simplify(); } inline Element operator*(const Element& X); //重載運算子「*」 inline Element operator/(const Element& X); //重載運算子「/」 inline Element operator+(const Element& X); //重載運算子「+」 inline Element operator-(const Element& X); //重載運算子「-」 inline void operator=(const Element& X); //重載運算子「=」 inline bool operator==(const Element& X); //重載運算子「==」 friend ostream& operator<<(ostream& output, const Element& X); //重載運算子「<<」 friend istream& operator>>(istream& input, Element& X); //重載運算子「>>」 private: int numerator, denominator; //分子;分母 bool interger; int __lcm(const int &a, const int &b){ return a * b / __gcd(a, b); } inline void simplify(){ //簡化分數 if (denominator != 1){ int r = __gcd(numerator, denominator); numerator /= r, denominator /= r; } if(denominator < 0){ numerator *= -1, denominator *= -1; } interger = (denominator == 1 or denominator == -1 ? true : false); } }; inline Element Element::operator*(const Element& X){ Element tmp(numerator * X.numerator, denominator * X.denominator); tmp.simplify(); return tmp; }; inline Element Element::operator/(const Element& X){ Element tmp(numerator * X.denominator, denominator * X.numerator); tmp.simplify(); return tmp; }; inline Element Element::operator+(const Element& X){ Element tmp(0, 1); tmp.denominator = __lcm(denominator, X.denominator);; tmp.numerator = tmp.denominator / denominator * numerator + tmp.denominator / X.denominator * X.numerator; tmp.simplify(); return tmp; }; inline Element Element::operator-(const Element& X){ Element tmp(0, 1); tmp.denominator = __lcm(denominator, X.denominator);; tmp.numerator = tmp.denominator / denominator * numerator - tmp.denominator / X.denominator * X.numerator; tmp.simplify(); return tmp; }; inline void Element::operator=(const Element& X){ this->numerator = X.numerator, this->denominator = X.denominator; simplify(); } inline bool Element::operator==(const Element& X){ return numerator == X.numerator and denominator == X.denominator; }; inline ostream& operator<<(ostream& output, const Element& X){ if (X.interger)output << X.numerator; else output << X.numerator << '/' << X.denominator; return output; } inline istream& operator>>(istream& input, Element& X){ string str; input >> str; int x = 0, y = 0, negative = (str[0] == '-' ? -1 : 1); bool gate = true; for (unsigned i = 0; i < str.size(); i++){ if (str[i] == '/'){ gate = false; } else if (str[i] >= '0' and str[i] <= '9'){ if (gate)x = x * 10 + str[i] - '0'; else y = y * 10 + str[i] - '0'; } } X.numerator = x * negative; X.denominator = (y == 0 ? 1 : y); return input; } ```