深圳大学计软《面向对象的程序设计》实验15 函数模板和类模板

A. 有界数组模板类(类模板)

题目描述

编写有界数组模板BoundArray(即检查对数组元素下标引用并在下标越界时终止程序的执行),能够存储各种类型的数据。要求实现对数组进行排序的方法sort,及对数组进行查找的方法search

输入

第一行先输入t,表示有t个测试用例

从第二行开始输入每个测试用例的数据。

首先输入数据类型,I表示intD表示doubleC表示char,接着输入数组的元素个数

然后输入每个元素

最后输入要查找的元素

输出

首先输出从小到大排序的元素

然后输出查找元素的结果,找到则输出下标,没找到则输出-1

输入样例1

2
I 2
1 2
2
D 3
3.5 6.2 2.9
2.1

输出样例1

1 2
1
2.9 3.5 6.2
-1

AC代码

#include<bits/stdc++.h>
using namespace std;

template<class T>
class BoundArray {
	int size;
	T* p;
public:
	BoundArray() {
		cin >> size;
		p = new T[size];
		for (int i = 0; i < size; i++)
			cin >> p[i];
	}

	~BoundArray()
	{
		delete[]p;
	}

	void sort() {
		make_heap(p, p + size);
		sort_heap(p, p + size);
	}

	int search(T key) {
		for (int i = 0; i < size; i++) {
			if (key == p[i])
				return i;
		}
		return -1;
	}

	void print() {
		for (int i = 0; i < size; i++)
			cout << p[i] << " ";
		cout << endl;
	}


};


int main() {
	int t;
	cin >> t;
	while (t--)
	{
		char ch;
		cin >> ch;
		if (ch == 'I') {
			BoundArray<int>l;
			l.sort();
			l.print();
			int key;
			cin >> key;
			cout << l.search(key) << endl;
		}
		else if (ch == 'D') {
			BoundArray<double>l;
			l.sort();
			l.print();
			double key;
			cin >> key;
			cout << l.search(key) << endl;
		}
		else if (ch == 'C') {
			BoundArray<char>l;
			l.sort();
			l.print();
			char key;
			cin >> key;
			cout << l.search(key) << endl;
		}


	}
	return 0;
}

B. 简单类模板(类模板)

题目描述

定义一个列表类,该列表包含属性:数值列表(用长度为100的数组表示),数据长度(实际的数据个数);包含的方法:初始化、插入、删除、打印,方法定义为:

1)初始化,接受外来参数,把数据保存在数值列表中,未使用的列表部分全部初始化为-1

2)插入,接受外来参数的插入位置和插入数值,插入位置从0开始计算,注意从插入位置开始,原有数据都要往后移动一位,且数据长度+1

3)删除,接受外来参数的删除位置,删除位置从0开始计算,注意从删除位置后一位开始,原有数据都要往前移动一位,且数据长度-1

4)打印,把包含的数据按位置顺序输出一行,数据之间单个空格隔开

使用类模板的方法,使得这个类支持整数int类型和浮点数double类型

输入

第一行先输入参数n表示有n个数据,接着输入n个整数

第二行输入两个参数,表示插入位置和插入数值,数值为整数

第三行输入删除位置

第四行先输入参数n表示有n个数据,接着输入n个浮点数

第五行输入两个参数,表示插入位置和插入数值,数值为浮点数

第六行输入删除位置

输出

针对头三行输入,分别执行初始化、插入操作和删除操作,调用打印方法输出列表包含的整数数据

针对接着的三行输入,分别执行初始化、插入操作和删除操作,调用打印方法输出列表包含的浮点数数据

输入样例1

5 11 22 33 44 55
2 888
4
5 1.1 2.2 3.3 4.4 5.5
2 88.8
3

输出样例1

11 22 888 33 55
1.1 2.2 88.8 4.4 5.5

#include<bits/stdc++.h>
using namespace std;

template<class T>
class List {
	vector<T>v;
public:
	List() {
		int len;
		cin >> len;
		v.resize(len);
		for (auto& it : v)
			cin >> it;
	}

	void insert(int index, T value) {
		v.insert(v.begin() + index, value);
	}

	void remove(int index) {
		v.erase(v.begin() + index);
	}

	void print() {
		for (int i = 0; i < v.size(); i++) {
			if (i)
				cout << " ";
			cout << v[i];
		}
		cout << endl;
	}

};

int main() {
	List<int>l1;
	int idx, value;
	cin >> idx >> value;
	l1.insert(idx, value);
	cin >> idx;
	l1.remove(idx);
	l1.print();

	List<double>l2;
	int idx1;
	double value1;
	cin >> idx1 >> value1;
	l2.insert(idx1, value1);
	cin >> idx1;
	l2.remove(idx1);
	l2.print();

	return 0;
}

C. 矩阵类模板(类模板)

题目描述

设计一个矩阵类模板Matrix,支持任意数据类型的数据。

要求至少包含2个成员函数:矩阵转置函数transport、以及打印输出函数print

编写main函数进行测试,调用类的成员函数完成转置和输出。

输入

第一行先输入t,表示有t个测试用例

从第二行开始输入每个测试用例的数据。

首先输入数据类型,I表示int,D表示double,C表示char,接着输入两个参数m和n,分别表示矩阵的行和列

接下来输入矩阵的元素,一共m行,每行n个数据

输出

输出转置后的矩阵

输入样例1

2
I 2 3
1 2 3
4 5 6
C 3 3
a b c
d e f
g h i

输出样例1

1 4
2 5
3 6
a d g
b e h
c f i

AC代码

#include<bits/stdc++.h>
using namespace std;

template<class T>
class Matrix {
	vector<vector<T>>v;
	int n, m;
public:
	Matrix() {
		cin >> n >> m;
		v.resize(n);
		for (int i = 0; i < n; i++)
			v[i].resize(m);
		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				cin >> v[i][j];
	}

	void transport() {
		vector<vector<T>>v1;
		v1.resize(m);
		for (int i = 0; i < m; i++)
			v1[i].resize(n);

		for (int i = 0; i < n; i++)
			for (int j = 0; j < m; j++)
				v1[j][i] = v[i][j];
		v = v1;
		swap(n, m);
	}

	void print() {
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (j)cout << " ";
				cout << v[i][j];
			}
			cout << endl;
		}
	}
};

int main() {
	int t;
	cin >> t;
	while (t--)
	{
		char ch;
		cin >> ch;
		if (ch == 'I') {
			Matrix<int>m;
			m.transport();
			m.print();
		}
		else if (ch == 'D') {
			Matrix<double>m;
			m.transport();
			m.print();
		}else if (ch == 'C') {
			Matrix<char>m;
			m.transport();
			m.print();
		}
	}
	return 0;
}

D. 排序函数模板

题目描述

编写一个对n个元素的数组升序排序的函数模板mysort,其中元素类型可以是基本数据类型,也可以是点对象(按点到原点的距离比较)。(要求不能用C++提供的sort函数模板)

输入

第一行输入测试次数

每次测试输入二行,第1行先输入一个大写字母表示数组类型,I表示整数类型,S表示字符串型,D表示双精度数类型,P表示点,最后输入n表示数组长度。第2行输入n个数据。

输出

每次测试输出一行排序后的结果

输入样例1

4
I 10
15 3 51 27 9 35 78 14 65 8
D 3
-11.3 25.42 13.2
P 6
1.1 2.2 2.4 -6.5 12 32 1.2 1.3 -3.5 0.1 9.2 1.1
S 4
sandy david eason cindy

输出样例1

3 8 9 14 15 27 35 51 65 78
-11.3 13.2 25.42
(1.2, 1.3) (1.1, 2.2) (-3.5, 0.1) (2.4, -6.5) (9.2, 1.1) (12.0, 32.0)
cindy david eason sandy

AC代码

#include<bits/stdc++.h>
using namespace std;

template<class T>
class MySort;

class Point {
	double x, y;
	template<class T>
	class MySort;
public:
	Point() {}

	double getDistance() const {
		return sqrt(x * x + y * y);
	}

	bool operator <(const Point& p)const {
		return getDistance() < p.getDistance();
	}

	friend ostream& operator << (ostream& output, Point& p) //定义运算符“<<”重载函数
	{
		output << fixed << setprecision(1) << "(" << p.x << ", " << p.y << ")";
		return output;
	}

	friend istream& operator >> (istream& input, Point& p) //定义运算符“<<”重载函数
	{
		input >> p.x >> p.y;
		return input;
	}


};



template<class T>
class MySort {
	vector<T>v;
	class Point;
public:
	MySort() {
		int size;
		cin >> size;
		v.resize(size);
		for (auto& it : v) {
			cin >> it;
		}

		make_heap(v.begin(), v.end());
		sort_heap(v.begin(), v.end());

		for (int i = 0; i < size; i++) {
			cout << v[i] << " ";
		}
		cout << endl;
	}
};

int main() {
	int t;
	cin >> t;
	while (t--)
	{
		char ch;
		cin >> ch;
		if (ch == 'I') {
			MySort<int>s;
		}
		else if (ch == 'D') {
			MySort<double>s;
		}
		else if (ch == 'S') {
			MySort<string>s;
		}
		else if (ch == 'P') {
			MySort<Point>s;
		}

	}
	return 0;
}

E. 对象相加函数模板

题目描述

时钟类CClock有时、分、秒;人民币类CRmb有元、角、分三个数据成员。试为这种类型的类对象定义一个两两相加的函数模板add,包括三个参数:2个对象和一个int表示进制。(要求不能用函数重载的方法)

主函数如下所示:

CClock c1(…), c2(…), c;

c = add(c1, c2, 60);

cout << c << endl;

CRmb r1(…), r2(…), r;

r = add(r1, r2, 10);

cout << r << endl;

输入

第一个时钟对象的时分秒

第二个时钟对象的时分秒

第一个人民币对象的元角分

第二个人民币对象的元角分

输出

两个时钟对象相加的结果

两个人民币对象相加的结果

输入样例1

15 34 25
7 25 36
5 6 7
3 4 5

输出样例1

23 0 1
9 1 2

AC代码

#include<bits/stdc++.h>
using namespace std;

class CClock {
	int h, m, s;
public:
	CClock() {
		cin >> h >> m >> s;
	}

	CClock(int h, int m, int s) :
		h(h),
		m(m),
		s(s) {}

	template<class T>
	friend T add(T, T, int);
	int getSumSecond(int n) {
		return s + m * n + h * n * n;
	}

	friend CClock add(CClock& a, CClock& b, int n) {
		int sum = a.getSumSecond(n) + b.getSumSecond(n);
		int hour = sum / (n * n);
		sum = sum % (n * n);
		int minu = sum / n;
		int sece = sum % n;
		return CClock(hour, minu, sece);
	}

	void print() {
		cout << h << " " << m << " " << s;
	}

	friend ostream& operator << (ostream& output, CClock& p) //定义运算符“<<”重载函数
	{
		p.print();
		return output;
	}

};

class RMB {
	int y, j, f;
public:
	RMB(int y, int j, int f) :y(y), j(j), f(f)
	{

	}

	RMB() { cin >> y >> j >> f; }

	int getSumFen(int n) {
		return f + j * n + y * n * n;
	}



	friend RMB add(RMB& a, RMB& b, int n) {
		int sum = a.getSumFen(n) + b.getSumFen(n);
		int hour = sum / (n * n);
		sum = sum % (n * n);
		int minu = sum / n;
		int sece = sum % n;
		return RMB(hour, minu, sece);
	}

	void print() {
		cout << y << " " << j << " " << f;
	}

	friend ostream& operator << (ostream& output, RMB& p) //定义运算符“<<”重载函数
	{
		p.print();
		return output;
	}

	template<class T>
	friend T add(T, T, int);
};

template<class T>
T add(T a, T b, int n) {
	return add(a, b, n);
}

int main() {
	CClock c1, c2;
	CClock c = add(c1, c2, 60);
	cout << c << endl;
	RMB r1, r2;
	RMB r = add(r1, r2, 10);
	cout << r << endl;
	return 0;
}

F. 逆序输出函数模板

题目描述

编写一个逆序输出数据的函数模板reverse(复数的逆序是实部虚部置换)。

输入

第一行输入测试次数

每次测试输入一行,先输入一个大写字母表示数据类型, I表示整型、D表示双精度型、S表示string类型字符串、C表示复数类对象,最后输入数据。

输出

每次测试输出一行,逆序排列的数据

输入样例1

5
I 123456
D -235.172
S thisisatest
C -123 456
C 123 -456

输出样例1

654321
-271.532
tsetasisiht
456-123
-456+123

提示

可用类型转换函数将复数类对象转换为string.模板函数内采用如下所示的方法可将数值型变量a转换成string型变量s:#include “sstream”…ostringstream os;string s; os << a; s = os.str();

#include<bits/stdc++.h>
using namespace std;

class Complex {
	double r, i;
public:
	Complex() { cin >> r >> i; }

	friend ostream& operator<<(ostream& output, Complex& c) {
		output << c.r;
		if (!c.i)
			return output;
		if (c.i > 0)
			cout << "+";
		cout << c.i;
		return output;
	}

	friend istream& operator>>(istream& input, Complex& c) {
		input >> c.r >> c.i;
		return input;
	}


	friend void reverse(Complex&c) {
		swap(c.r, c.i);
		cout << c << endl;
	}

};



template<class T>
void reverse(T t) {
	string s = to_string(t);
	//if (typeid(t) == typeid(double)) {
	//	while (*s.rbegin()=='0'){
	//		s.pop_back();
	//	}
	//}

	reverse(s.begin(), s.end());

	if (*s.rbegin() == '-') {
		s.pop_back();
		cout << "-";
	}
	
	if (typeid(t) == typeid(int)) {
		cout << stoi(s) << endl;
		return;
	}

	if (typeid(t) == typeid(double)) {
		cout << stod(s) << endl;
		return;
	}

	cout << s << endl;
}

void reverse(string &s) {
	reverse(s.begin(), s.end());
	cout << s << endl;
}



int main() {
	int t;
	cin >> t;
	while (t--)
	{
		char ch;
		cin >> ch;
		string t1;
		if (ch == 'I') {
			int t1;
			cin >> t1;
			reverse<int>(t1);
		}
		else if (ch == 'D') {
			double t1;
			cin >> t1;
			reverse<double>(t1);
		}
		else if (ch == 'S') {
			string t1;
			cin >> t1;
			reverse(t1);
		}

		else {
			Complex t1;
			reverse(t1);
		}

	}

}

G. 链表类模板

题目描述

结点数据类型为int的单链表类CIntList可定义如下:

class CNode

{

public:

int data;

CNode *next;

};

class CIntList

{

private:

CNode *head;

public:

CIntList();

void append(int a); //加到链表最后

void insert(int a, int n); //在第n个结点后加

void remove(int n); //移除第n个结点

int get(int n); //返回第n个结点的数据

void set(int a, int n); //将第n个节点的数据改成a

void print();

~CIntList();

};

试将其改成结点数据类型用参数表示的类模板CList。

输入

第一行输入测试次数

每次测试输入5行,格式为:

数据类型(I:int, D:double, S:string) 数据个数n 数据1 数据2 … 数据n

插入节点号(0表示插在第1个结点前面) 数据

返回结点号

删除结点号

修改结点号 数据

输出

每次测试输出二行.第1行输出返回操作获得的数据(如出错则输出error),第2行输出所有操作后链表全部结点的数据.

输入样例1

3
I 5 2 3 5 7 3
1 40
7
7
6 -10
D 6 1.1 2.3 10.05 0.0 -1.8 5.9
4 60.4
5
1
3 -3.7
S 4 this is a test.
0 good
1
8
4 work

输出样例1

error
2 40 3 5 7 -10
60.4
2.3 10.05 -3.7 60.4 -1.8 5.9
good
good this is work test.

AC代码

#include<bits/stdc++.h>
using namespace std;

template<class T>
struct CNode
{
	T data;
	CNode<T>* next;
	CNode() { next = NULL; }
	CNode(T d, CNode<T>* n = NULL) {
		data = d;
		next = n;
	}
};

template<class T>
class List {
	int len;
	CNode<T>* head;
public:
	List() {
		cin >> len;
		head = new CNode<T>;
		CNode<T>* p = head;
		for (int i = 0; i < len; i++) {
			p->next = new CNode<T>;
			p = p->next;
			cin >> p->data;
		}
	}

	void append(T a) {
		CNode<T>p = head;
		while (p) {
			p = p->next;
		}
		p = new CNode<T>(a);
		len++;
	}

	void insert(T a, int n) {
		if (n < 0 || n > len)
			return;

		CNode<T>* p = head;

		for (int i = 0; i < n; i++) {
			p = p->next;
		}

		CNode<T>* s = new CNode<T>(a, p->next);
		p->next = s;
		len++;
	}

	void remove(int n) {
		if (n < 0 || n >= len)
			return;

		CNode<T>* p = head;
		for (int i = 0; i < n; i++) {
			p = p->next;
		}
		CNode<T>* s = p->next;
		p->next = s->next;
		delete s;
		len--;
	}

	void set(T a, int n) {
		if (n < 0 || n >= len)
			return;
		CNode<T>* p = head->next;
		for (int i = 0; i < n; i++) {
			p = p->next;
		}
		p->data = a;
	}

	void print() {
		CNode<T>* p;
		for (p = head->next; p->next; p = p->next)
			cout << p->data << " ";
		cout << p->data << endl;
	}

	T get(int n) {
		CNode<T>* p = head->next;
		for (int i = 0; i < n; i++)
			p = p->next;
		return p->data;
	}

	int getSize() { return len; }
};

int main() {
	int t;
	cin >> t;
	while (t--)
	{
		char ch;
		cin >> ch;
		if (ch == 'I') {
			List<int>l;
			int a;
			int n;
			cin >> n >> a;
			l.insert(a, n);

			cin >> n;
			if (n<1 || n>l.getSize()) {
				puts("error");
			}
			else {
				cout << l.get(n - 1) << endl;
			}

			cin >> n;
			l.remove(n - 1);

			cin >> n >> a;
			l.set(a, n - 1);

			l.print();
		}
		else if (ch == 'D') {
			List<double>l;
			double a;
			int n;
			cin >> n >> a;
			l.insert(a, n);

			cin >> n;
			if (n<1 || n>l.getSize()) {
				puts("error");
			}
			else {
				cout << l.get(n - 1) << endl;
			}

			cin >> n;
			l.remove(n - 1);

			cin >> n >> a;
			l.set(a, n - 1);

			l.print();
		}
		else if (ch == 'S') {
			List<string>l;
			string a;
			int n;
			cin >> n >> a;
			l.insert(a, n);

			cin >> n;
			if (n<1 || n>l.getSize()) {
				puts("error");
			}
			else {
				cout << l.get(n - 1) << endl;
			}

			cin >> n;
			l.remove(n - 1);

			cin >> n >> a;
			l.set(a, n - 1);

			l.print();
		}

	}
}
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曹无悔

请支持我的梦想!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值