C++实验课
lab2_3
题目
补充实验:成绩表里找同学
【问题描述】
编写一个程序,读入 N 个同学的姓名和语数外三门功课的单科成绩,对其按照一定的排序规则排序形成一张成绩表(先按总分从高到低排序,总分相同则按语文成绩由高到低排序,仍然相同则按数学成绩由高到低排序,若总分和单科成绩均相同则最后按姓名的字典序排序)。最后给定一个数字 K(K<=N) ,输出在这张排好序的成绩表中位置在第 K 位的同学的姓名和总分。
字典序举例说明:
abc > abd
a > aa
要求:用C++对象数组表示学生数据。采用多文件结构,类的声明放在头文件如student.h,类的实现放在源文件如student.cpp。
【输入形式】
第一行输入一个正整数 N(1<=N<=1024),代表接下来将录入 N 个学生的成绩。
接下来 N 行录入 N 条学生的成绩记录,每条记录依次为姓名,语文成绩,数学成绩,英语成绩,这四个字段以空格分隔。姓名为字符串(仅包含小写字母,不含空格,长度<=19),学生之间不会重名。三科成绩均为整数(0~100)。
最后输入一个正整数 K(1<=K<=N),代表需要在成绩表中从前往后找到的位置。
【输出形式】
在成绩表中从前往后处在第 K 位的同学的姓名和总分,中间以空格分隔。
【样例输入1】
2
tom 90 91 92
lucy 91 90 92
1
【样例输出1】
lucy 273
【样例输入2】
4
lily 90 100 88
jack 87 79 95
hanz 90 89 71
david 90 89 71
4
【样例输出2】
hanz 250
解答
lab2_3_Stu.h C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #pragma once #include <iostream> #include <string> using namespace std; class Student { public: string name; int yu; int shu; int wai; int sum; Student() {} Student(string name, int yu, int shu, int wai) :name(name), yu(yu), shu(shu), wai(wai) {} void setInfo(); };
lab2_3_Stu.cpp C++ 1 2 3 4 5 6 7 8 #include "lab2_3_Stu.h" void Student::setInfo() { cin >> this->name; cin >> this->yu; cin >> this->shu; cin >> this->wai; sum = this->yu + this->wai + this->shu; }
lab2_3.cpp C++ 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 #include <iostream> #include <string> using namespace std; #include <vector> #include <algorithm> #include "lab2_3_Stu.h" class Mypred { public: bool operator()(Student s1, Student s2) { if (s1.sum == s2.sum) { return s1.name < s2.name; } else { return s1.sum > s2.sum; } } }; class ScoreSheet { public: int numOfStu; vector<Student> vstus; void initSheet() { cin >> numOfStu; vstus.resize(numOfStu); for (int i = 0; i < numOfStu; i++) { Student stu; stu.setInfo(); vstus[i] = stu; } sort(vstus.begin(), vstus.end(), Mypred()); } void queeryCode() { int code; cin >> code; cout << vstus[code-1].name << " " << vstus[code-1].sum << endl; } }; int main() { ScoreSheet ss; ss.initSheet(); ss.queeryCode(); return 0; }
分文件, 我这里只分了一个
分文件方法:
.h 中放声明, .cpp中放实现, 主函数中引用 .h
或者.hpp中放声明和实现, 主函数中引用 .hpp
这题很典型, vector容器储存, sort算法排序传个谓词进去, 不同排序的方式由谓词实现.
lab3_1
题目
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 编写一个学生和教师数据输入和显示程序。其中,学生数据有编号、姓名、班级和成绩,教师数据有编号、姓名、职称和部门。 要求: (1)将编号、姓名输入和显示设计成一个类person; (2)设计类person的派生类:学生类student和教师类teacher; (3)主函数中分别定义一个学生对象和教师对象进行测试。 【输入形式】 程序参考的输入(输入数据前面为提示文字): Input id:1 Input name:zhangsan Input class:1 Input score:90 Input id:2 Input name:lisi Input title:teacher Input department:computer 【输出形式】 程序参考的输出: Student's info: Id:1 Name:zhangsan Class:1 Score:90 Teacher's info: Id:2 Name:lisi Title:teacher Department:computer
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 #include <iostream> #include <string> using namespace std;class person { public : person () { cout << "Input id:" ; cin >> id; cout << "Input name:" ; cin >> name; } void display () { cout << "Id:" << id << endl; cout << "Name:" << name << endl; } private : string id; string name; }; class student : public person{public : student () { cout << "Input class:" ; cin >> classNum; cout << "Input score:" ; cin >> score; } void display () { cout << "Student's info:" << endl; person::display (); cout << "Class:" << classNum << endl; cout << "Score:" << score << endl; } private : string classNum; int score; }; class teacher : public person {public : teacher () { cout << "Input title:" ; cin >> title; cout << "Input department:" ; cin >> department; } void display () { cout << "Teacher's info:" << endl; person::display (); cout << "Title:" << title << endl; cout << "Department:" << department << endl; } private : string title; string department; }; int main () { student stu; teacher tea; stu.display (); tea.display (); return 0 ; }
一开始想了半天调用父类的private成员要用友元, 又不能更改题目, 后来才发现不是给了公共display接口么. 写派生类多关注公共接口, 私有的不需要管.
lab3_2
题目
补充:字符串统计排序,继承系统string类
【问题描述】
编写一个程序,接收用户输入的一个字符串(可以包含空格),统计其中所有出现过的所有字符,并按照频率高低的顺序排列输出。频率相同的字符按输入顺序输出。
【输入形式】
用户在第一行输入一个字符串,以回车结束输入。
【输出形式】
程序统计字符串中出现的所有字符,然后按照字符出现频率大小排序输出,频率相同时,按输入顺序输出。输出形式规定为每行输出4个字符数据,输出格式为:字符-出现次数。每个字符-出现次数输出中间用一个空格分隔,每行末尾没有空格。程序输出结尾有一个回车。
【样例输入】
The job requires an agile mind.
【样例输出】
#-5 e-4 i-3 r-2
a-2 n-2 T-1 h-1
j-1 o-1 b-1 q-1
u-1 s-1 g-1 l-1
m-1 d-1 .-1 #表示空格(在程序请输出空格,而不是字符"#",这里只是表示而已。)
【样例说明】
用户首先输入字符串The job requires an agile mind. 程序统计完毕之后按照每行4个统计结果输出,字符串中有5个空格,所以输出为#-5,#表示空格。字符’b’和’T’出现次数同为1,因为输入时’b’先于’T’输入,所以输出时也先打印’b’的统计信息。
解答
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 #include <iostream> #include <string> using namespace std;class MyChar { public : MyChar () :num (0 ) {} char ch; int num; }; class MyString : public string{ public : void input () { getline (cin, *this ); sum = 0 ; } void putchar (char ch) ; void compute () ; void output () ; private : MyChar chars[300 ]; int sum; }; void MyString::putchar (char ch) { for (int i = 0 ; i < sum; i++) { if (chars[i].ch == ch) { chars[i].num++; return ; } } chars[sum].ch = ch; chars[sum].num++; sum++; } void MyString::compute () { for (int i = 0 ; i < (*this ).size (); i++) { putchar ((*this )[i]); } for (int i = 0 ; i < sum - 1 ; i++) { for (int j = 0 ; j < sum - i - 1 ; j++) { if (chars[j].num < chars[j + 1 ].num) { MyChar temp = chars[j]; chars[j] = chars[j + 1 ]; chars[j + 1 ] = temp; } } } } void MyString::output () { for (int i = 1 ; i <= sum; i++) { cout << chars[i - 1 ].ch << "-" << chars[i - 1 ].num << " " ; if (i % 4 == 0 ) cout << endl; } } int main () { MyString s; s.input (); s.compute (); s.output (); return 0 ; }
要看懂每一个函数是做什么, getline(cin, *this);, 用到了多态, *this是string的派生类, 父类指针指向子类对象.
chars[]中的是引用对象, 交换位置的时候交换引用就行了, 而不是值交换.
lab5
两道分析题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 #include <iostream> #include <complex> using namespace std;class Base { public : Base () { cout << "Base-ctor" << endl; } ~Base () { cout << "Base-dtor" << endl; } virtual void f (int ) { cout << "Base::f(int)" << endl; } virtual void f (double ) { cout << "Base::f(double)" << endl; } virtual void g (int i = 10 ) { cout << "Base::g()" << i << endl; } }; class Derived : public Base{ public : Derived () { cout << "Derived-ctor" << endl; } ~Derived () { cout << "Derived-dtor" << endl; } void f (complex<double >) { cout << "Derived::f(complex)" << endl; } void g (int i = 20 ) { cout << "Derived::g()" << i << endl; } }; int main () { cout << sizeof (Base) << endl; cout << sizeof (Derived) << endl; Base b; Derived d; Base* pb = new Derived; b.f (1.0 ); d.f (1.0 ); pb->f (1.0 ); b.g (); d.g (); pb->g (); delete pb; return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 #include <iostream> using namespace std;class Base { public : Base () :data (count) { cout << "Base-ctor" << endl; ++count; } ~Base () { cout << "Base-dtor" << endl; --count; } static int count; int data; }; int Base::count;class Derived : public Base{ public : Derived () :data (count), data1 (data) { cout << "Derived-ctor" << endl; ++count; } ~Derived () { cout << "Derived-dtor" << endl; --count; } static int count; int data1; int data; }; int Derived::count = 10 ;int main () { cout << sizeof (Base) << endl; cout << sizeof (Derived) << endl; Base* pb = new Derived[3 ]; cout << pb[2 ].data << endl; cout << ((static_cast <Derived*>(pb)) + 2 )->data1 << endl; delete [] pb; cout << Base::count << endl; cout << Derived::count << endl; return 0 ; }
lab6
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 #include <iostream> #include <cmath> using namespace std;class CFraction { private : int nume; int deno; public : CFraction (int nu = 0 , int de = 1 ) :nume (nu), deno (de) {} void simplify () ; friend istream &operator >>(istream &in, CFraction &x); friend ostream &operator <<(ostream &out, CFraction x); CFraction operator +(const CFraction &c2){ int ldeno = deno * c2.deno; int lnume = nume * c2.deno + c2.nume * deno; CFraction temp (lnume, ldeno) ; temp.simplify (); return temp; } CFraction operator -(const CFraction &c2){ int ldeno = deno * c2.deno; int lnume = nume * c2.deno - c2.nume * deno; CFraction temp (lnume, ldeno) ; temp.simplify (); return temp; } CFraction operator *(const CFraction &c2){ int ldeno = deno * c2.deno; int lnume = nume * c2.nume; CFraction temp (lnume, ldeno) ; temp.simplify (); return temp; } CFraction operator /(const CFraction &c2){ CFraction rotate (c2.deno, c2.nume) ; return *this *rotate; } }; istream& operator >>(istream &in, CFraction &x){ char temp; in >> x.nume >> temp >> x.deno; return in; } ostream& operator <<(ostream &out, CFraction x){ if (x.deno == 1 ){ out << x.nume << endl; } else out << (x.nume < 0 ? showpos : noshowpos) << x.nume << "/" << noshowpos << x.deno; return out; } inline int gcd (int a, int b) { a = abs (a); b = abs (b); int r; while (b > 0 ) { r = a % b; a = b; b = r; } return a; } void CFraction::simplify () { int common = gcd (deno, nume); nume /= common; deno /= common; } int main () { CFraction x, y, s; cout << "Input x: " ; cin >> x; cout << "Input y: " ; cin >> y; s = x + y; cout << "x+y=" << s << endl; s = x - y; cout << "x-y=" << s << endl; s = x*y; cout << "x*y=" << s << endl; s = x / y; cout << "x/y=" << s << endl; system ("pause" ); return 0 ; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 #include <iostream> #include <string> #include <string.h> using namespace std;#include <vector> class Matrix {public : vector<int > v; int i, j; Matrix (int i, int j) :i (i), j (j) { v.resize (i * j); } Matrix& operator =(const Matrix& m) { copy (m.v.begin (), m.v.end (), v.begin ()); j = m.j; i = m.i; return *this ; } friend ostream& operator <<(ostream& out, Matrix& m) { for (int p = 0 ; p < m.i; p++) { for (int q = 0 ; q < m.j; q++) { out << m.v[p * m.j + q] << " " ; } out << endl; } return out; } friend istream& operator >> (istream& in, Matrix& m) { for (int i = 0 ; i < m.v.size (); i++) cin >> m.v[i]; return in; } void operator +=(const Matrix& m) { if (i != m.i || j != m.j) cout << "ERROR!" << endl; else { for (int i = 0 ; i < m.v.size (); i++) v[i] += m.v[i]; cout << *this << endl; } } void operator *=(const Matrix& m) { if (j != m.i) cout << "ERROR!" << endl; else { Matrix res (i, m.j); for (int p = 0 ; p < res.i; p++) { for (int q = 0 ; q <res.j; q++) { for (int r = 0 ; r < j; r++) { res.v[p * res.j + q] = res.v[p * res.j + q] + v[p * j + r] * m.v[r * m.j + q]; } } } copy (res.v.begin (), res.v.end (), v.begin ()); cout << *this << endl; } } int operator () (int a, int b) { return v[a * j + b]; } }; int main () { int row1, col1, row2, col2; cin >> row1 >> col1; Matrix m1 (row1, col1) ; cin >> m1; cin >> row2 >> col2; Matrix m2 (row2, col2) ; cin >> m2; cout << m1 (row1 / 2 , col1 / 2 ) << endl; m1 *= m2; m1 += m2; m1 = m2; cout << m1 << endl; return 0 ; }