由于c++理论课一直没有去上,实验课一开始又投机取巧没有按题目要求写,导致现在实验课上得有点头痛……决定开一篇把之前的实验重新规范写一下,放一些模板上来,上到哪写到哪吧。
指针 找数组最大值 code 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 #include <iostream> using namespace std;int FindArrayMax (int a[], int n) { int max = *a; for (int i = 0 ; i < n; i++) { if (*(a + i) > max) { max = *(a + i); } } return max; } int main () { const int MAXN = 10 ; int i, n; int a[MAXN]; cin >> n; for (i = 0 ; i < n; i++) { cin >> a[i]; } cout << FindArrayMax (a, n) << endl; return 0 ; }
基础指针调用。
动态矩阵 题目描述 未知一个整数矩阵的大小,在程序运行时才会输入矩阵的行数m和列数n
要求使用指针,结合new 方法,动态创建一个二维数组,并求出该矩阵的最小值和最大值,可以使用数组下标法。
不能先创建一个超大矩阵,然后只使用矩阵的一部分空间来进行数据访问、
创建的矩阵大小必须和输入的行数m和列数n一样
code 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 #include <iostream> using namespace std;int main () { int t; cin >> t; for (int u = 1 ; u <= t; u++) { int m, n; cin >> m >> n; int maxx; int minn; int **k = new int *[m]; for (int i = 0 ; i < m; i++) { k[i] = new int [n]; for (int j = 0 ; j < n; j++) { cin >> k[i][j]; if (i == 0 && j == 0 ) { maxx = k[i][j]; minn = k[i][j]; } else { maxx = max (maxx, k[i][j]); minn = min (minn, k[i][j]); } } } cout << minn << " " << maxx << "\n" ; for (int i = 0 ; i < m; i++) { delete [] k[i]; } delete [] k; } return 0 ; }
主要是熟悉如何建立动态数组和释放空间。
密钥加密法 题目描述 有一种方式是使用密钥进行加密的方法,就是对明文的每个字符使用密钥上对应的密码进行加密,最终得到密文
例如明文是abcde,密钥是234,那么加密方法就是a对应密钥的2,也就是a偏移2位转化为c;明文b对应密钥的3,就是b偏移3位转化为e,同理c偏移4位转化为g。这时候密钥已经使用完,那么又重头开始使用。因此明文的d对应密钥的2,转化为f,明文的e对应密钥的3转化为h。所以明文abcde,密钥234,经过加密后得到密文是cegfh。
如果字母偏移的位数超过26个字母范围,则循环偏移,例如字母z偏移2位,就是转化为b,同理字母x偏移5位就是转化为c
要求:使用三个指针 p、q、s分别指向明文、密钥和密文,然后使用指针p和q来访问每个位置的字符,进行加密得到密文存储在指针s指向的位置。
除了变量定义和输入数据,其他过程都不能使用数组下标法,必须使用三个指针来访问明文、密钥和密文。
提示:当指针q已经移动到密钥的末尾,但明文仍然没有结束,那么q就跳回密钥头
code 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 #include <cstring> #include <iostream> using namespace std;void solve (char &p, char &q, char &s) { int add = p + q; if (p >= 'a' && p <= 'z' ) { while (add > 'z' ) { add -= 26 ; } } else { while (add > 'Z' ) { add -= 26 ; } } s = add; } int main () { int t; cin >> t; for (int u = 0 ; u < t; u++) { char s[22 ]; char c[22 ]; cin >> s >> c; int k = 0 ; for (int i = 0 ; i < strlen (c); i++) { c[i] -= '0' ; c[i] %= 26 ; } for (int i = 0 ; i < strlen (s); i++) { char ans; solve (*(s + i), *(c + k), ans); cout << ans; k++; if (k == strlen (c)) { k = 0 ; } } cout << "\n" ; } return 0 ; }
其实就是比较繁琐的一道题……没什么难度,注意’z‘的ASCII值为122 ,但ASCII值只到127 ,直接加可能会超出这个范围导致变为负数,循环条件不成立导致输出有问题,我一开始就是踩到这个坑de了很久bug……
引用与结构 谁是老二 题目描述 定义一个结构体,包含年月日,表示一个学生的出生日期。然后在一群学生的出生日期中找出谁的出生日期排行第二
要求:出生日期的存储必须使用结构体 ,不能使用其他类型的数据结构。
要求程序全过程对出生日期的输入、访问、输出都必须使用结构。
code 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 #include <algorithm> #include <iostream> using namespace std;struct bir { int y, m, d; bool operator <(const bir &that) const { if (y != that.y) { return y < that.y; } else { if (m != that.m) { return m < that.m; } else { return d < that.d; } } } }; int main () { int n; cin >> n; bir a[n + 1 ]; for (int i = 0 ; i < n; i++) { cin >> a[i].y >> a[i].m >> a[i].d; } sort (a, a + n); cout << a[1 ].y << "-" << a[1 ].m << "-" << a[1 ].d; return 0 ; }
留个结构体运算符重载模板。
抄袭查找 题目描述 已知一群学生的考试试卷,要求对试卷内容进行对比,查找是否有抄袭。
每张试卷包含:学号(整数类型)、题目1答案(字符串类型)、题目2答案(字符串类型)、题目3答案(字符串类型)
要求:使用结构体 来存储试卷的信息。定义一个函数,返回值为一个整数,参数是两个结构体指针 ,函数操作是比较两张试卷的每道题目的答案,如果相同题号的答案相似度超过90%,那么就认为有抄袭,函数返回抄袭题号,否则返回0。相似度是指在同一题目中,两个答案的逐个位置上的字符两两比较,相同的数量大于等于任一个 答案的长度的90%,就认为抄袭。
code 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 #include <iostream> using namespace std;struct aa { string s; string ans[3 ]; }; int solve (aa &a, aa &b) { int p = 0 ; for (int i = 0 ; i < 3 ; i++) { int len = min (a.ans[i].length (), b.ans[i].length ()); int cnt = 0 ; for (int j = 0 ; j < len; j++) { if (a.ans[i][j] == b.ans[i][j]) { cnt++; } } if ((cnt * 10 ) / len >= 9 ) { p = i + 1 ; break ; } } return p; } int main () { int n; cin >> n; aa a[n + 1 ]; for (int i = 0 ; i < n; i++) { cin >> a[i].s; for (int j = 0 ; j < 3 ; j++) { cin >> a[i].ans[j]; } } for (int i = 0 ; i < n - 1 ; i++) { for (int j = i + 1 ; j < n; j++) { int p = solve (*(a + i), *(a + j)); if (p != 0 ) { cout << a[i].s << " " << a[j].s << " " << p << "\n" ; } } } return 0 ; }
又是一道烦烦的繁琐题…练一下吧。抄什么袭!
类与对象 身体评估 题目描述 评估成年人身体健康有多个指标,包括BMI、体脂率等
设计一个身体健康类 ,包含私有成员 :姓名、身高(米)、体重(公斤),腰围(厘米),实现两个公有方法如下:
BMI方法,返回BMI数值(整数,四舍五入到个位),计算公式BMI= 体重 / 身高的平方
体脂率方法,返回体脂率数值(浮点数),计算过程如下:
1)参数a=腰围(cm)×0.74
2)参数b=体重(kg)×0.082+34.89
3)体脂肪重量(kg)=a-b
4)体脂率 = 体脂肪重量÷体重
其它方法根据需要自行定义
code 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 #include <iomanip> #include <iostream> using namespace std;class kk { private : string s; double h, w, y; public : void set (string ss, double hh, double ww, double yy) ; string gets () ; int bmi () ; double aa () ; double bb () ; double dd () ; }; void kk::set (string ss, double hh, double ww, double yy) { s = ss; h = hh; w = ww; y = yy; } string kk::gets () { return s; } int kk::bmi () { double bmii = w / (h * h); int bmi = bmii / 1 ; if (bmii - bmi >= 0.5 ) { bmi++; } return bmi; } double kk::aa () { return 0.74 * y; } double kk::bb () { return w * 0.082 + 34.89 ; } double kk::dd () { return (aa () - bb ()) / w; } int main () { int t; cin >> t; for (int u = 0 ; u < t; u++) { string s; double h, w, y; cin >> s >> h >> w >> y; kk a; a.set (s, h, w, y); cout << a.gets () << "的BMI指数为" << a.bmi () << "--体脂率为" << fixed << setprecision (2 ) << a.dd () << "\n" ; } return 0 ; }
掌握class内如何构造函数,如何给类内参数赋值,如何用get访问类内参数。其他操作和结构体类似。
构造与析构 分数类 题目描述 完成下列分数类的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 class CFraction { private : int fz, fm; public : CFraction (int fz_val, int fm_val); CFraction add (const CFraction &r) ; CFraction sub (const CFraction &r) ; CFraction mul (const CFraction &r) ; CFraction div (const CFraction &r) ; int getGCD () ; void print () ; };
求两数a、b的最大公约数可采用辗转相除法,又称欧几里得算法,其步骤为:
交换a, b使a > b;
用a除b得到余数r,若r=0,则b为最大公约数,退出.
若r不为0,则用b代替a, r代替b,此时a,b都比上一次的小,问题规模缩小了;
继续第2步。
注意:如果分母是1的话,也按“分子/1”的方式输出。
code 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 #include <iostream> using namespace std;class cf { private : int m, s; public : cf (int ss, int mm); cf add (const cf &that) ; cf sub (const cf &that) ; cf mul (const cf &that) ; cf div (const cf &that) ; int gcd () ; void print () ; }; int cf::gcd () { int a = s; int b = m; while (b != 0 ) { int t = a % b; a = b; b = t; } return a; } cf::cf (int ss, int mm) { s = ss; m = mm; } cf cf::add (const cf &that) { int ss = m * that.s + that.m * s; int mm = m * that.m; return cf (ss, mm); } cf cf::sub (const cf &that) { int ss = s * that.m - that.s * m; int mm = m * that.m; return cf (ss, mm); } cf cf::mul (const cf &that) { int ss = s * that.s; int mm = m * that.m; return cf (ss, mm); } cf cf::div (const cf &that) { int ss = s * that.m; int mm = m * that.s; return cf (ss, mm); } void cf::print () { int g = gcd (); s /= g; m /= g; if (m < 0 ) { m *= -1 ; s *= -1 ; } cout << s << "/" << m << "\n" ; } int main () { int t; cin >> t; for (int i = 0 ; i < t; i++) { int s1, s2, m1, m2; scanf ("%d/%d" , &s1, &m1); scanf ("%d/%d" , &s2, &m2); cf f1 (s1, m1) , f2 (s2, m2) ; cf add = f1. add (f2); add.print (); cf sub = f1. sub (f2); sub.print (); cf mul = f1. mul (f2); mul.print (); cf div = f1. div (f2); div.print (); cout << "\n" ; } return 0 ; }
构造构造构造……意会一下吧。
Point_Array 题目描述
上面是我们曾经练习过的一个习题,请在原来代码的基础上作以下修改:
增加自写的析构函数;
将getDisTo方法的参数修改为getDisTo(const Point &p);
根据输出的内容修改相应的构造函数。
然后在主函数中根据用户输入的数目建立Point数组,求出数组内距离最大的两个点之间的距离值。
code 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 #include <cmath> #include <iomanip> #include <iostream> using namespace std;class point { private : double x, y; public : ~point (); point (); point (double xx, double yy); double getx () ; double gety () ; void set (double xx, double yy) ; void setx (double xx) ; void sety (double yy) ; double dis (const point &p) ; }; point::~point () { cout << "Distructor.\n" ; } point::point () { x = 0 ; y = 0 ; cout << "Constructor.\n" ; } point::point (double xx, double yy) { set (xx, yy); } void point::set (double xx, double yy) { setx (xx); sety (yy); } void point::setx (double xx) { x = xx; } void point::sety (double yy) { y = yy; } double point::dis (const point &p) { double dx = x - p.x; double dy = y - p.y; return sqrt (dx * dx + dy * dy); } double point::getx () { return x; } double point::gety () { return y; } int main () { int t; cin >> t; for (int u = 0 ; u < t; u++) { int n; cin >> n; point *p = new point[n]; for (int i = 0 ; i < n; i++) { double x, y; cin >> x >> y; p[i].set (x, y); } double maxx = 0 ; int a = 0 ; int b = 0 ; for (int i = 0 ; i < n - 1 ; i++) { for (int j = i + 1 ; j < n; j++) { double dd = p[i].dis (p[j]); if (dd > maxx) { maxx = dd; a = i; b = j; } } } cout << "The longest distance is " << fixed << setprecision (2 ) << maxx << ",between p[" << a << "] and p[" << b << "].\n" ; delete [] p; } return 0 ; }
就多了个析构函数的步骤。
Stack 题目描述
上面是栈类的定义,栈 是一种具有先进后出特点的线性表,请根据注释,完成类中所有方法的实现,并在主函数中测试之。
堆栈类的说明如下:
堆栈的数据实际上是保存在数组a中,而a开始是一个指针,在初始化时,根据实际需求将a动态创建为数组,数组长度根据构造函数的参数决定。
size实际上就是数组的长度,当使用无参构造则size为10,当使用有参构造则size为s、
top表示数组下标,也表示数组中下一个存放数据的空白位置。
push操作表示堆栈的数组存放一个数据,例如一开始数组为空,则top为0,当有数据要入栈时,把数据存放在a[top]的位置,然后top加1指向下一个空白位置、数据进栈只能从栈顶进。
pop操作表示一个数据要出栈,数据出栈只能从栈顶出,先把top减1指向栈顶数据,然后把数据返回。
判断堆栈空的条件是top是否等于0,判断堆栈满的条件是top是否等于size
code 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 #include <iostream> using namespace std;class cstack { public : cstack (); cstack (int s); int get (int index) ; void push (int n) ; int emptyy () ; int full () ; int pop () ; ~cstack (); private : int *a; int size; int top; }; cstack::cstack () { a = nullptr ; size = 0 ; top = 0 ; cout << "Constructor.\n" ; } cstack::cstack (int s) { a = new int [s]; size = s; top = 0 ; cout << "Constructor.\n" ; } int cstack::get (int index) { return *(a + index); } void cstack::push (int n) { *(a + top) = n; top++; } int cstack::emptyy () { if (top == 0 ) { return 1 ; } return 0 ; } int cstack::full () { if (top == size) { return 1 ; } return 0 ; } int cstack::pop () { top--; return *(a + top); } cstack::~cstack () { delete [] a; cout << "Destructor.\n" ; } int main () { int t; cin >> t; for (int u = 0 ; u < t; u++) { int n; cin >> n; cstack *s = new cstack (n); while (!s->full ()) { int x; cin >> x; s->push (x); } while (!s->emptyy ()) { if (!s->full ()) { cout << " " ; } cout << s->pop (); } cout << "\n" ; delete s; } return 0 ; }
原理差不多,练练手吧。好想用stack……