C++:【练习题】类模版

习题1

1.1 题目:

编写一个函数模板,分别求一个组数里面数据的最大值,最小值和平均值。

1.2 解题思路:

  • 定义模板类型T
  • 编写函数MathHelper求数组数据的最大值、最小值和平均值
  • 用double和int两组数据进行测试

1.3 代码及注释:

#include<iostream>
using namespace std;

//求一个数列的最大值、最小值、均值
template<typename T>
void MathHelper(T num[], int size) {
	T max = num[0], min = num[0], total = 0;
	for (int i = 0;i < size;i++) {
		if (num[i] > max)
			max = num[i];
		if (num[i] < min)
			min = num[i];
		total += num[i];
	}
	//显示最大值、最小值、均值
	cout << "Max  : " << max << endl;
	cout << "Min  : " << min << endl;
	if (size == 0)
		cout << "Mean : " << 0 << endl;
	else
		cout << "Mean : " << total / double(size) << endl;
}

void main() {
	//测试
	int a[10] = { 2,1,9,10,7,6,5,8,3,4 };
	double b[10] = { 2.5,1.5,9.5,10.5,7.5,6.5,5.5,8.5,3.5,4.5 };
	MathHelper<int>(a, sizeof(a) / sizeof(a[0]));
	cout << endl;
	MathHelper<double>(b, sizeof(b) / sizeof(b[0]));
}

1.4 程序运行结果分析:

构造两个不同类型的数组数据进行测试,结果如下:

Max  : 10
Min  : 1
Mean : 5.5

Max  : 10.5
Min  : 1.5
Mean : 6
请按任意键继续. . .

验证可得程序执行正确。

习题2

2.1 题目:

编写一个函数模板,实现数据交换的操作。

2.2 解题思路:

  • 定义模板类型T
  • 编写函数Swap对两个相同类型的数据进行互换
  • 用double、int和char三种不同类型的数据进行实验

2.3 代码及注释:

#include<iostream>
using namespace std;

// 定义交换函数Swap
template<typename T>
void Swap(T& a, T& b) {
	T c = a;
	a = b;
	b = c;
}


int main() {
	// 测试数据
	int a1 = 10, b1 = -8;
	cout << "Before swapping:" << endl;
	cout << "a1 = " << a1 << endl;
	cout << "b1 = " << b1 << endl;
	Swap<int>(a1, b1);
	cout << "After swapping:" << endl;
	cout << "a1 = " << a1 << endl;
	cout << "b1 = " << b1 << endl << endl;

	double a2 = 10.35, b2 = -11.23;
	cout << "Before swapping:" << endl;
	cout << "a2 = " << a2 << endl;
	cout << "b2 = " << b2 << endl;
	Swap<double>(a2, b2);
	cout << "After swapping:" << endl;
	cout << "a2 = " << a2 << endl;
	cout << "b2 = " << b2 << endl << endl;

	char a3 = 'K', b3 = 'E';
	cout << "Before swapping:" << endl;
	cout << "a3 = " << a3 << endl;
	cout << "b3 = " << b3 << endl;
	Swap<char>(a3, b3);
	cout << "After swapping:" << endl;
	cout << "a3 = " << a3 << endl;
	cout << "b3 = " << b3 << endl << endl;
}

2.4 程序运行结果分析:

构造的三组不同类型的数据,测试结果如下:

Before swapping:
a1 = 10
b1 = -8
After swapping:
a1 = -8
b1 = 10

Before swapping:
a2 = 10.35
b2 = -11.23
After swapping:
a2 = -11.23
b2 = 10.35

Before swapping:
a3 = K
b3 = E
After swapping:
a3 = E
b3 = K

请按任意键继续. . .

因此,程序执行正确。

习题3

3.1 题目:

编写如下形式的排序函数模板:

template<class Type>void sort(Type* A, int n, bool f)

对一个具有n个Type类型的一维数组进行排序,f为1表示从小到大排序,f为0表示从大到小排序,并通过不同参数类型机型调用,验证正确性。

注意:

  • int double char型至少三种类型进行测试,int和double类型数组内容建议使用random()生成
  • 排序前的状态和排序后的状态都应该进行输出
  • 注意是在原始的数组上进行排序,不能新开辟数组

3.2 解题思路:

  • 定义模板类型T
  • 编写Sort函数对数组数据进行排序
  • 排序算法中,快排、堆排、归并排序等算法平均时间复杂度都是o(nlogn)级别的,这里我们采用快排对数据进行排序。
  • 编写Display函数对数据进行展示
  • 利用随机种子和伪随机数对int、double、char三个类型的数据进行赋值
  • 验证结果的合理性

3.3 代码及注释:

#include<iostream>
#include<cstdlib>
#include<ctime>
using namespace std;

// 编写Sort函数,传参进快速排序
template<typename T>
void Sort(T* A, int n, bool f) {
    QuickSort(A, 0, n - 1, f);
}

// 快速排序算法
template<typename T>
void QuickSort(T arr[], int left, int right, bool f) {
    if (left >= right)return;
    T key = arr[left];
    int i = left + 1;
    int j = right;
    while (true) {
        if (f) {
            while (arr[i] < key) {
                if (i == right)break;
                i++;
            }
            while (arr[j] > key) {
                if (j == left)break;
                j--;
            }
        }
        else {
            while (arr[i] > key) {
                if (i == right)break;
                i++;
            }
            while (arr[j] < key) {
                if (j == left)break;
                j--;
            }
        }
        
        if (j <= i)break;
        T temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }
    T temp = arr[j];
    arr[j] = arr[left];
    arr[left] = temp;
    QuickSort(arr, left, j - 1, f);
    QuickSort(arr, j + 1, right, f);
}

// 显示数组内数据
template<typename T>
void Display(T* A, int n) {
    for (int i = 0; i < n; i++)
        cout << A[i] << " ";
    cout << endl;
}

void main() {
    srand(time(0));

    // 对int类型数组进行测试
    int a[10];
    for (int i = 0; i < 10; i++)
        a[i] = rand() % 100 * pow(-1, rand());
    cout << "Befor sorting :" << endl;
    Display<int>(a, 10);
    cout << "After sorting :" << endl;
    Sort<int>(a, 10, 0);
    Display<int>(a, 10);
    Sort<int>(a, 10, 1);
    Display<int>(a, 10);
    cout << endl << endl;

    // 对double类型数组进行测试
    double b[10];
    for (int i = 0; i < 10; i++)
        b[i] = (rand() % 100) * pow(-1, rand()) / 7;
    cout << "Befor sorting :" << endl;
    Display<double>(b, 10);
    cout << "After sorting :" << endl;
    Sort<double>(b, 10, 0);
    Display<double>(b, 10);
    Sort<double>(b, 10, 1);
    Display<double>(b, 10);
    cout << endl << endl;

    // 对char类型数组进行测试
    char c[10];
    for (int i = 0; i < 10; i++)
        c[i] = (rand() % 74) + 48;
    cout << "Befor sorting :" << endl;
    Display<char>(c, 10);
    cout << "After sorting :" << endl;
    Sort<char>(c, 10, 0);
    Display<char>(c, 10);
    Sort<char>(c, 10, 1);
    Display<char>(c, 10);
    cout << endl << endl;
}

3.4 程序运行结果分析:

我们设置不同的值对其进行调试,其中包括三个不同的类型,测试结果如下:

Befor sorting :
53 85 63 -91 53 79 20 -86 49 3
After sorting :
85 79 63 53 53 49 20 3 -86 -91
-91 -86 3 20 49 53 53 63 79 85


Befor sorting :
-11.8571 -1.71429 14 -10.2857 -4.28571 -1.85714 4.28571 -7.57143 9.28571 -4.14286
After sorting :
14 9.28571 4.28571 -1.71429 -1.85714 -4.14286 -4.28571 -7.57143 -10.2857 -11.8571
-11.8571 -10.2857 -7.57143 -4.28571 -4.14286 -1.85714 -1.71429 4.28571 9.28571 14


Befor sorting :
i n E ] r D g j O 6
After sorting :
r n j i g ] O E D 6
6 D E O ] g i j n r


请按任意键继续. . .

验证三组测试实验表明,程序执行正确。

习题4

4.1 题目:

编写一个类模板,完成对不同数据类型的数组的排序(小到大)操作。

如:

  • int array[5]={3,6,2,1,4};
  • double array[5]={3.1,1.2,4.5,1.1,0.2};

4.2 解题思路:

  • 创建Sort类
  • 定义QuickSort方法,利用快速排序对数据进行排序
  • 重载cout函数输出结果

4.3 代码及注释:

#include<iostream>
using namespace std;

// 定义Sort类
template<class T>
class Sort {
public:
	Sort(T A[], int len_) { arr = A; len = len_; }
	void QuickSort() { QuickSort(0, len - 1); }
	void Display(ostream& out)const {
		for (int i = 0; i < len; i++) out << arr[i] << " ";
	}
private:
	void QuickSort(int left, int right);
	T* arr;
	int len;
};

// 利用快速排序算法对数据进行排序
template<class T>
void Sort<T>::QuickSort(int left, int right) {
	if (left >= right)
		return;
	T key = arr[left];
	int i = left + 1;
	int j = right;
	while (true) {
		while (arr[i] < key) {
			if (i == right)break;
			i++;
		}
		while (arr[j] > key) {
			if (j == left)break;
			j--;
		}
		if (i >= j)break;
		T temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
	T temp = arr[j];
	arr[j] = arr[left];
	arr[left] = temp;
	QuickSort(left, j - 1);
	QuickSort(j + 1, right);
}

// 重载cout函数
template<class T>
ostream& operator<<(ostream& out, const Sort<T>& A) {
	A.Display(out);
	return out;
}


int main() {
	// 测试题目给定数据
	int a[5] = { 3,6,2,1,4 };
	Sort<int> sort_a(a, 5);
	cout << "排序前:" << sort_a << endl;
	sort_a.QuickSort();
	cout << "排序后:" << sort_a << endl << endl;


	double b[5] = { 3.1,1.2,4.5,1.1,0.2 };
	Sort<double> sort_b(b, 5);
	cout << "排序前:" << sort_b << endl;
	sort_b.QuickSort();
	cout << "排序后:" << sort_b << endl << endl;

	return 0;
}

4.4 程序运行结果分析:

根据题目数据进行测试,结果如下:

排序前:3 6 2 1 4
排序后:1 2 3 4 6

排序前:3.1 1.2 4.5 1.1 0.2
排序后:0.2 1.1 1.2 3.1 4.5

请按任意键继续. . .

因此,程序执行正确。

习题5

5.1 题目:

定义一个堆栈类模板,实现不同数据类型数据的入栈和出栈操作,堆栈的大小用非类型参数指定。

5.2 解题思路:

  • 定义Stack类,堆栈的大小用非类型参数指定
  • 编写Stack类的成员方法
  • 重载cout函数
  • 利用try-catch方法进行异常捕获和处理
  • 进行调试测验

5.3 代码及注释:

#include<iostream>
using namespace std;

// 定义Stack类
template<class T, int MaxSize>
class Stack {
public:
	Stack() {
		elems = new T[MaxSize];
		top = -1;
	}
	~Stack() { delete elems; }
	bool IsEmpty()const { return top == -1; }
	bool IsFull()const { return top == MaxSize; }
	T Top()const;
	Stack<T, MaxSize>& Push(const T& x);
	Stack<T, MaxSize>& Pop(T& x);
	void Display()const;
private:
	int top;
	T * elems;
};

// 返回Stack首元素
template<class T, int MaxSize>
T Stack<T, MaxSize>::Top()const {
	if (IsEmpty())
		throw out_of_range("Stack<>::Top(): empty stack");
	return elems[top];
}

// 进行Push操作
template<class T, int MaxSize>
Stack<T, MaxSize>& Stack<T, MaxSize>::Push(const T& x) {
	if (IsFull())
		throw out_of_range("Stack<>::Push(): full stack");
	elems[++top] = x;
	return *this;
}

// 进行Pop操作
template<class T, int MaxSize>
Stack<T, MaxSize>& Stack<T, MaxSize>::Pop(T& x) {
	if (IsEmpty())
		throw out_of_range("Stack<>::Pop(): empty stack");
	x = elems[top--];
	return *this;
}

// 显示Stack内所有元素,从栈底到栈顶依次显示
template<class T, int MaxSize>
void Stack<T, MaxSize>::Display()const {
	if (IsEmpty())
		cout << "None" << endl;
	else {
		for (int i = 0;i <= top;i++)
			cout << elems[i] << "  ";
	}
}

// 重载ostream成员函数cout
template<class T, int MaxSize>
ostream& operator<<(ostream& out,const Stack<T, MaxSize>& s) {
	s.Display();
	return out;
}

int main() {
	// 构造不同数据类型进行测试验证
	try {
		Stack<int, 10> stack_int;
		for (int i = 0;i < 10;i++)
			stack_int.Push(5 * i);
		cout << "stack_int: " << stack_int << endl;
		cout << "delete two elements: ";
		for (int i = 0;i < 2;i++) {
			int x;
			stack_int.Pop(x);
			cout << x << "  ";
		}
		cout << endl << "stack_int: " << stack_int << endl << endl << endl;

		Stack<double, 10> stack_double;
		for (int i = 0;i < 10;i++)
			stack_double.Push(5.2 * i + 0.3);
		cout << "stack_double: " << stack_double << endl;
		cout << "delete two elements: ";
		for (int i = 0;i < 2;i++) {
			double x;
			stack_double.Pop(x);
			cout << x << "  ";
		}
		cout << endl << "stack_double: " << stack_double << endl << endl << endl;

		Stack<char, 10> stack_char;
		for (int i = 0;i < 10;i++)
			stack_char.Push(2 * i + 68);
		cout << "stack_char: " << stack_char << endl;
		cout << "delete two elements: ";
		for (int i = 0;i < 2;i++) {
			char x;
			stack_char.Pop(x);
			cout << x << "  ";
		}
		cout << endl << "stack_char: " << stack_char << endl << endl << endl;
		return 0;
	}
	catch (exception& ex) {
		cout << ex.what() << endl;
		return EXIT_FAILURE;
	}
}

5.4 程序运行结果分析:

我们对Stack类构建了三种不同的数据类型进行测试,实验结果如下:

stack_int: 0  5  10  15  20  25  30  35  40  45
delete two elements: 45  40
stack_int: 0  5  10  15  20  25  30  35


stack_double: 0.3  5.5  10.7  15.9  21.1  26.3  31.5  36.7  41.9  47.1
delete two elements: 47.1  41.9
stack_double: 0.3  5.5  10.7  15.9  21.1  26.3  31.5  36.7


stack_char: D  F  H  J  L  N  P  R  T  V
delete two elements: V  T
stack_char: D  F  H  J  L  N  P  R


请按任意键继续. . .

由实验结果可知:程序执行正确。

习题6

6.1 题目:

用类模板创建单链表,并实现在链表里增加一个节点和删除一个节点的操作。

6.2 解题思路:

  • 定义链表结点类Node
  • 定义链表类List
  • 编写List成员方法
  • 重载cout函数输出
  • 利用try-catch方法进行异常调试
  • 构造三种不同类型的数据进行测试

6.3 代码及注释:

#include<iostream>
using namespace std;

// 定义链表结点类Node
template<class T>
class Node {
public:
	T data;
	Node<T>* next;
};

// 定义链表类List
template<class T>
class List {
public:
	List() { first = 0; }
	bool IsEmpty() { return first == 0; }
	int Length()const;
	List<T>& Insert(int num, const T& x);
	List<T>& Delete(int num, T& x);
	void Display(ostream& out) const;
private:
	Node<T>* first;
};

// 返回链表长度
template<class T>
int List<T>::Length()const {
	int num = 0;
	for (Node<T>* current = first; current; current = current->next)
		num++;
	return num;
}

// 插入元素
template<class T>
List<T>& List<T>::Insert(int num, const T& x) {
	if (num < 0)
		throw out_of_range("List<>::Insert():error num");
	Node<T>* current = first;
	for (int i = 1; i < num && current; i++)
		current = current->next;
	if (!current && num > 0)
		throw out_of_range("List<>::Insert():error num");
	Node<T>* p = new Node<T>;
	p->data = x;
	if (num) {
		p->next = current->next;
		current->next = p;
	}
	else {
		p->next = first;
		first = p;
	}
	return *this;
}

// 删除元素
template<class T>
List<T>& List<T>::Delete(int num, T& x) {
	if (num < 1 || first == 0)
		throw out_of_range("List<>::Delete():error num");
	Node<T>* current = first;
	if (num == 1)
		first = first->next;
	else {
		Node<T>* p = first;
		for (int i = 1; i < num - 1 && p; i++)
			p = p->next;
		if (!p || !p->next)
			throw out_of_range("List<>::Delete():error num");
		current = p->next;
		p->next = current->next;
	}
	x = current->data;
	delete current;
	return *this;
}

// 展示元素
template<class T>
void List<T>::Display(ostream& out)const {
	for (Node<T>* current = first; current; current = current->next)
		out << current->data << "  ";
}

// 重载cout函数
template<class T>
ostream& operator<<(ostream& out, const List<T>& A) {
	A.Display(out);
	return out;
}

int main() {
	try {
		// 创建三种不同类型的数据进行调试测验
		List<char> list_char;
		list_char.Insert(0, 'a');
		list_char.Insert(0, 'b');
		list_char.Insert(0, 'c');
		list_char.Insert(0, 'd');
		cout << "原来的List        :" << list_char << endl;
		list_char.Insert(0, 'e');
		cout << "添加首元素后的List:" << list_char << endl;
		char x;
		list_char.Delete(5, x);
		cout << "删除尾元素后的List:" << list_char << endl << endl;

		List<double> list_double;
		list_double.Insert(0, 1.32);
		list_double.Insert(0, 2.34);
		list_double.Insert(0, 11.2);
		list_double.Insert(0, 5.6);
		cout << "原来的List        :" << list_double << endl;
		list_double.Insert(0, 3.08);
		cout << "添加首元素后的List:" << list_double << endl;
		double y;
		list_double.Delete(5, y);
		cout << "删除尾元素后的List:" << list_double << endl << endl;

		List<int> list_int;
		list_int.Insert(0, 11);
		list_int.Insert(0, 23);
		list_int.Insert(0, 36);
		list_int.Insert(0, 20);
		cout << "原来的List        :" << list_int << endl;
		list_int.Insert(0, 37);
		cout << "添加首元素后的List:" << list_int << endl;
		int z;
		list_int.Delete(5, z);
		cout << "删除尾元素后的List:" << list_int << endl << endl;

		return EXIT_SUCCESS;
	}
	catch (exception& ex) {
		cout << ex.what() << endl;
		return EXIT_FAILURE;
	}
}

6.4 程序运行结果分析:

构建三种不同的数据类型进行测试,结果如下:

原来的List        :d  c  b  a
添加首元素后的List:e  d  c  b  a
删除尾元素后的List:e  d  c  b

原来的List        :5.6  11.2  2.34  1.32
添加首元素后的List:3.08  5.6  11.2  2.34  1.32
删除尾元素后的List:3.08  5.6  11.2  2.34

原来的List        :20  36  23  11
添加首元素后的List:37  20  36  23  11
删除尾元素后的List:37  20  36  23


请按任意键继续. . .

由结果得,程序执行正确。

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值