实验6
实验一代码:
1 #pragma once 2 3 #include <iostream> 4 #include <stdexcept> 5 6 // 声明 7 //////////////////////////////////////////////////// 8 // 复数模板类声明 9 template<typename T> 10 class Complex { 11 public: 12 Complex(T r = 0, T i = 0); 13 Complex(const Complex<T> &c); 14 15 T get_real() const; 16 T get_imag() const; 17 18 // 重载+=为成员函数 19 Complex<T>& operator+=(const Complex<T> &c); 20 21 // 重载<<、>>为友元函数 22 template<typename T1> 23 friend std::ostream& operator<<(std::ostream &out, const Complex<T1> &c); 24 25 template<typename T1> 26 friend std::istream& operator>>(std::istream &in, Complex<T1> &c); 27 28 private: 29 T real, imag; 30 }; 31 32 // 普通函数声明 33 // 重载+用于Complex类型 34 template<typename T> 35 Complex<T> operator+(const Complex<T> &c1, const Complex<T> &c2); 36 37 // 重载==用于Complex类型 38 template<typename T> 39 bool operator==(const Complex<T> &c1, const Complex<T> &c2); 40 41 42 // 实现 43 //////////////////////////////////////////////////// 44 // 成员函数模板实现 45 template<typename T> 46 Complex<T>::Complex(T r, T i): real{r}, imag{i} { 47 } 48 49 template<typename T> 50 Complex<T>::Complex(const Complex<T> &c): real{c.real}, imag{c.imag} { 51 } 52 53 template<typename T> 54 T Complex<T>::get_real() const { 55 return real; 56 } 57 58 template<typename T> 59 T Complex<T>::get_imag() const { 60 return imag; 61 } 62 63 // 重载+=为成员函数 64 template<typename T> 65 Complex<T>& Complex<T>::operator+=(const Complex<T> &c) { 66 real += c.real; 67 imag += c.imag; 68 69 return *this; 70 } 71 72 /////////////////////////////////////// 73 // 友元函数模板实现 74 template<typename T1> 75 std::ostream& operator<<(std::ostream &out, const Complex<T1> &c) { 76 if(c.imag >= 0) 77 out << c.real << " + " << c.imag << "i"; 78 else 79 out << c.real << " - " << -c.imag << "i"; 80 81 return out; 82 } 83 84 template<typename T1> 85 std::istream& operator>>(std::istream &in, Complex<T1> &c) { 86 in >> c.real >> c.imag; 87 88 return in; 89 } 90 91 /////////////////////////////////////// 92 // 普通函数模板实现 93 // 重载+用于Complex类型 94 template<typename T> 95 Complex<T> operator+(const Complex<T> &c1, const Complex<T> &c2) { 96 return Complex<T>(c1.get_real()+c2.get_real(), 97 c1.get_imag()+c2.get_imag()); 98 } 99 100 // 重载==用于Complex类型 101 template<typename T> 102 bool operator==(const Complex<T> &c1, const Complex<T> &c2) { 103 return c1.get_real() == c2.get_real() && 104 c1.get_imag() && c2.get_imag(); 105 } 106 107 108 109 110 #include "Complex.hpp" 111 #include <iostream> 112 #include <fstream> 113 #include <stdexcept> 114 115 void test1(); 116 void test2(); 117 118 int main() { 119 using namespace std; 120 121 cout << "测试1: 复数模板类测试" << endl; 122 test1(); 123 124 cout << "\n测试2: 文件I/O测试" << endl; 125 test2(); 126 } 127 128 void test1() { 129 using namespace std; 130 131 Complex<double> c1{3.5, 2}, c2; 132 cout << "Enter c2: "; 133 cin >> c2; 134 cout << "c1 = " << c1 << endl; 135 cout << "c2 = " << c2 << endl; 136 cout << "c1 == c2: " << boolalpha << (c1 == c2) << endl; 137 138 cout << "c1 + c2 = " << c1 + c2 << endl; 139 c1 += c2; 140 cout << "c1.real = " << c1.get_real() << endl; 141 cout << "c1.imag = " << c1.get_imag() << endl; 142 143 cout << "c1 == c2: " << boolalpha << (c1 == c2) << endl; 144 } 145 146 void test2() { 147 using namespace std; 148 149 Complex<int> c1{1, 2}, c2{9, -7}; 150 ofstream out("ans.txt"); 151 if(!out.is_open()) { 152 cout << "fail to open file ans.txt to write\n"; 153 return; 154 } 155 156 out << "c1 = " << c1 << endl; 157 out << "c2 = " << c2 << endl; 158 out << "c1 + c2 = " << c1 + c2 << endl; 159 out << "(c1 == c2) = " << boolalpha << (c1 == c2) << endl; 160 161 out.close(); 162 cout << "测试ok!" << endl; 163 }
运行截图:
实验二代码:
1 #pragma once 2 3 #include <iostream> 4 #include <iomanip> 5 #include <string> 6 7 using std::string; 8 using std::ostream; 9 using std::istream; 10 using std::setw; 11 using std::setprecision; 12 using std::setiosflags; 13 using std::ios_base; 14 15 // Contestant类声明 16 class Contestant { 17 public: 18 Contestant() = default; 19 ~Contestant() = default; 20 21 int get_num() const { return num; } 22 float get_time_usage() const { return time_usage; } 23 24 friend ostream& operator<<(ostream &out, const Contestant &c); 25 friend istream& operator>>(istream &in, Contestant &c); 26 27 private: 28 string no; // 学号 29 string name; // 姓名 30 string major; // 专业 31 int num; // 解题数 32 float time_usage; // 总用时 33 }; 34 35 // 友元函数实现 36 // 重载流插入运算符<< 37 ostream& operator<<(ostream &out, const Contestant &c) { 38 out << setiosflags(ios_base::left); 39 out << setw(15) << c.no 40 << setw(15) << c.name 41 << setw(15) << c.major 42 << setw(5) << c.num 43 << setprecision(2) << c.time_usage; 44 45 return out; 46 } 47 48 // 重载流提取运算符>> 49 istream& operator>>(istream &in, Contestant &c) { 50 in >> c.no >> c.name >> c.major >> c.num >> c.time_usage; 51 52 return in; 53 } 54 55 56 57 58 #include "Contestant.hpp" 59 #include "utils.hpp" 60 #include <iostream> 61 #include <vector> 62 #include <algorithm> 63 64 65 void test() { 66 using namespace std; 67 68 vector<Contestant> v; 69 70 load("data2.txt", v); // 从文件加载选手信息到对象v 71 sort(v.begin(), v.end(), compare_by_solutionInfo); // 按解题情况排序 72 output(cout, v); // 输出对象v中信息到屏幕 73 save("ans.txt", v); // 把对象v中选手信息保存到文件 74 } 75 76 int main() { 77 test(); 78 } 79 80 81 82 83 #include "Contestant.hpp" 84 #include <fstream> 85 #include <iostream> 86 #include <string> 87 #include <vector> 88 89 // 排序函数 90 // 按解题数比较,解题数相同的情况下,按总用时比较,总用时越少,排名越靠前 91 bool compare_by_solutionInfo(const Contestant &c1, const Contestant &c2) { 92 if(c1.get_num() > c2.get_num()) 93 return true; 94 95 if(c1.get_num() == c2.get_num()) 96 return c1.get_time_usage() < c2.get_time_usage(); 97 98 return false; 99 } 100 101 // 把vector<Constestant>对象中的元素插入到输出流out 102 void output(std::ostream &out, const std::vector<Contestant> &v) { 103 for(auto &i: v) 104 out << i << std::endl; 105 } 106 107 108 // 把vector<Contestant>对象中的元素写到filename文件中 109 void save(const std::string &filename, std::vector<Contestant> &v) { 110 using std::ofstream; 111 112 ofstream out(filename); 113 if(!out.is_open()) { 114 std::cout << "fail to open file to write\n"; 115 return; 116 } 117 118 output(out, v); 119 out.close(); 120 } 121 122 // 从文件filename读取参赛选手信息到vector<Contestant>对象 123 void load(const std::string &filename, std::vector<Contestant> &v) { 124 using std::ifstream; 125 126 ifstream in(filename); 127 if(!in.is_open()) { 128 std::cout << "fail to open file to read\n"; 129 return; 130 } 131 132 std::string title_line; 133 getline(in, title_line); // 跳过标题行 134 135 int first_column; 136 Contestant t; 137 while(in >> first_column >> t) 138 v.push_back(t); 139 140 in.close(); 141 }
运行截图:
实验三代码:
1 #include <iostream> 2 #include <stdexcept> 3 #include <cmath> 4 5 using namespace std; 6 7 class Triangle { 8 public: 9 Triangle(double s1, double s2, double s3); 10 ~Triangle() = default; 11 12 double area() const; 13 14 private: 15 double a, b, c; 16 }; 17 18 Triangle::Triangle(double s1, double s2, double s3): a{s1}, b{s2}, c{s3} { 19 if(a <= 0 || b <= 0 || c <= 0) 20 throw invalid_argument("边长出现负值"); 21 22 if(a+b <= c || b+c <= a || a+c <= b) 23 throw invalid_argument("不满足任意两边之和大于第三边"); 24 } 25 26 double Triangle::area() const { 27 double s = (a + b + c)/2; 28 return sqrt(s*(s-a)*(s-b)*(s-c)); 29 } 30 31 32 33 34 #include "Triangle.hpp" 35 #include <iostream> 36 #include <fstream> 37 38 void test() { 39 using namespace std; 40 41 cout << "从文件读入三角形三边边长,计算面积" << endl; 42 43 ifstream in("data3.txt"); 44 if(!in.is_open()) { 45 cout << "fail to open file to read\n"; 46 return; 47 } 48 49 double a,b,c; 50 do { 51 cout << "三角形边长: "; 52 in >> a >> b >> c; 53 cout << a << " " << b << " " << c << endl; 54 55 try { 56 Triangle t(a, b, c); 57 cout << "三角形面积: " << t.area() << endl << endl; 58 }catch(const exception &e) { 59 cout << "error: " << e.what() << endl << endl; 60 } 61 62 if(in.peek() == EOF) 63 break; 64 } while(1); 65 66 in.close(); 67 } 68 69 int main() { 70 test(); 71 }
运行截图:
实验四代码:
1 #pragma once 2 3 #include<iostream> 4 #include<stdexcept> 5 6 using namespace std; 7 8 template<class T> 9 class Vector{ 10 public: 11 Vector(int n):size(n){ 12 if(n<0) 13 throw length_error("Vector constructor: nagative size"); 14 ptr=new T[size]; 15 } 16 Vector(int n,T value):size(n){ 17 if(n<0) 18 throw length_error("Vector constructor: nagative size"); 19 ptr=new T[size]; 20 for(int i=0;i<size;i++) 21 ptr[i]=value; 22 } 23 Vector(const Vector &v):size(v.size),ptr(new int[size]){ 24 for(int i=0;i<size;i++) 25 ptr[i]=v.ptr[i]; 26 } 27 ~Vector(){ 28 delete[] ptr; 29 } 30 int get_size() const{ 31 return size; 32 } 33 T& at(int index) const{ 34 if(index<0||index>=size) 35 throw length_error("Vector constructor: nagative size"); 36 return ptr[index]; 37 } 38 T operator[](int index){ 39 if(index<0||index>=size) 40 throw length_error("Vector constructor: nagative size"); 41 return ptr[index]; 42 } 43 template<class T1> 44 friend void output(Vector<T1> const &v); 45 private: 46 int size; 47 T *ptr; 48 }; 49 50 51 template<class T1> 52 void output(Vector<T1> const &v){ 53 for(int i=0;i<v.size;i++) 54 cout<<v.ptr[i]<<" "; 55 cout<<endl; 56 } 57 58 59 60 61 62 63 #include <iostream> 64 #include "Vector.hpp" 65 66 void test1() { 67 using namespace std; 68 69 int n; 70 cout << "Enter n: "; 71 cin >> n; 72 73 Vector<double> x1(n); 74 for(auto i = 0; i < n; ++i) 75 x1.at(i) = i * 0.7; 76 77 cout << "x1: "; output(x1); 78 79 Vector<int> x2(n, 42); 80 const Vector<int> x3(x2); 81 82 cout << "x2: "; output(x2); 83 cout << "x3: "; output(x3); 84 85 x2.at(0) = 77; 86 x2.at(1) = 777; 87 cout << "x2: "; output(x2); 88 cout << "x3: "; output(x3); 89 } 90 91 void test2() { 92 using namespace std; 93 94 int n, index; 95 while(cout << "Enter n and index: ", cin >> n >> index) { 96 try { 97 Vector<int> v(n, n); 98 v.at(index) = -999; 99 cout << "v: "; output(v); 100 } 101 catch (const exception &e) { 102 cout << e.what() << endl; 103 } 104 } 105 } 106 107 int main() { 108 cout << "测试1: 模板类接口测试\n"; 109 test1(); 110 111 cout << "\n测试2: 模板类异常处理测试\n"; 112 test2(); 113 }
运行截图:
实验五代码:
1 #include<iostream> 2 #include<iomanip> 3 #include<string> 4 #include<fstream> 5 #include<algorithm> 6 #include<vector> 7 8 using namespace std; 9 10 class Grade{ 11 public: 12 Grade(const string &Num,const string &Name,const string &Major,int Score); 13 ~Grade()=default; 14 15 int get_score() const{return score;} 16 string get_major() const{return major;} 17 string get_num()const{return num;} 18 string get_name()const{return name;} 19 private: 20 string num; 21 string name; 22 string major; 23 int score; 24 }; 25 26 Grade::Grade(const string &Num,const string &Name,const string &Major,int Score):num{Num},name{Name},major{Major},score{Score}{} 27 28 bool compare_Grade(const Grade& G1,const Grade& G2){ 29 if(G1.get_major()<G2.get_major())return true; 30 else if(G1.get_major()>G2.get_major())return false; 31 return G1.get_score()>G2.get_score(); 32 } 33 34 int main(){ 35 vector<Grade>grades; 36 ifstream in("data5.txt"); 37 if(in.is_open()){ 38 string line; 39 getline(in,line); 40 41 string num,name,major; 42 int score; 43 while(in>>num>>name>>major>>score){ 44 grades.push_back(Grade(num,name,major,score)); 45 } 46 in.close(); 47 } 48 else{ 49 cout<<"fail to open file to read\n"; 50 return 1; 51 } 52 53 sort(grades.begin(),grades.end(),compare_Grade); 54 55 ofstream out("ans5.txt"); 56 if(out.is_open()){ 57 for(const Grade&g:grades){ 58 out<<g.get_num()<<" "<<g.get_name()<<" "<<g.get_major()<<" "<<g.get_score()<<endl; 59 cout<<left; 60 cout<<setw(15)<<g.get_num()<<setw(15)<<g.get_name()<<setw(15)<<g.get_major()<<setw(15)<<g.get_score()<<endl; 61 } 62 } 63 else{ 64 cout<<"fail to open file to write\n"; 65 return 1; 66 } 67 return 0; 68 }
运行截图: