




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C+程序设计课内实验03数学与应用数学201446谭毓银曾悦16实验09 群体类与群体数据的组织(4学时)(第9章 群体类与群体数据的组织)一、实验目的(1) 掌握函数模板与类模板。(2) 了解线性群体与群体数据的组织。二、实验任务9_1求绝对值的函数模板及其应用#include <iostream>using namespace std;template<typename T>T fun(T x) return x < 0? -x : x;int main() int n = -5;double d = -5.5;cout << fun(n) <
2、;< endl;cout << fun(d) << endl;return 0;9_2函数模板的示例。#include <iostream>using namespace std;template <class T>/定义函数模板void outputArray(const T *array, int count)for (int i = 0; i < count; i+)cout << arrayi << " "cout << endl;int main() /主函数const
3、 int A_COUNT = 8, B_COUNT = 8, C_COUNT = 20;int a A_COUNT = 1, 2, 3, 4, 5, 6, 7, 8 ;/定义int数组double bB_COUNT = 1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8 ; /定义double数组char cC_COUNT = "Welcome to see you!"/定义char数组cout << " a array contains:" << endl;outputArray(a, A_COUNT)
4、;/调用函数模板cout << " b array contains:" << endl;outputArray(b, B_COUNT);/调用函数模板cout << " c array contains:" << endl;outputArray(c, C_COUNT);/调用函数模板return 0;9_3类模板应用举例。#include <iostream>#include <cstdlib>using namespace std;/ 结构体Studentstruct Stud
5、ent int id; /学号 float gpa; /平均分; template <class T>class Store /类模板:实现对任意类型数据进行存取private:T item;/ item用于存放任意类型的数据bool haveValue; / haveValue标记item是否已被存入内容public:Store();/ 缺省形式(无形参)的构造函数T &getElem();/提取数据函数void putElem(const T &x); /存入数据函数;/以下实现各成员函数。template <class T>/缺省构造函数的实现 S
6、tore<T>:Store(): haveValue(false) template <class T> /提取数据函数的实现T &Store<T>:getElem() /如试图提取未初始化的数据,则终止程序if (!haveValue) cout << "No item present!" << endl;exit(1);/使程序完全退出,返回到操作系统。return item; / 返回item中存放的数据 template <class T>/存入数据函数的实现 void Store<
7、;T>:putElem(const T &x) / 将haveValue 置为true,表示item中已存入数值haveValue = true;item = x;/ 将x值存入itemint main() Store<int> s1, s2;s1.putElem(3);s2.putElem(-7);cout << s1.getElem() << " " << s2.getElem() << endl;Student g = 1000, 23 ;Store<Student> s3;s3.p
8、utElem(g); cout << "The student id is " << s3.getElem().id << endl;Store<double> d;cout << "Retrieving object D. "cout << d.getElem() << endl;/由于d未经初始化,在执行函数D.getElement()过程中导致程序终止return 0;9_4动态数据类模板示例/Array.h#ifndef ARRAY_H#define ARRAY_
9、H#include <cassert>/数组类模板定义template <class T> class Array private:T* list;/T类型指针,用于存放动态分配的数组内存首地址int size;/数组大小(元素个数)public:Array(int sz = 50);/构造函数Array(const Array<T> &a);/拷贝构造函数Array();/析构函数Array<T> & operator = (const Array<T> &rhs); /重载"="使数组对
10、象可以整体赋值T & operator (int i);/重载"",使Array对象可以起到C+普通数组的作用const T & operator (int i) const;/""运算符的const版本operator T * ();/重载到T*类型的转换,使Array对象可以起到C+普通数组的作用operator const T * () const;/到T*类型转换操作符的const版本int getSize() const;/取数组的大小void resize(int sz);/修改数组的大小;/构造函数template <
11、class T>Array<T>:Array(int sz) assert(sz >= 0);/sz为数组大小(元素个数),应当非负size = sz;/ 将元素个数赋值给变量sizelist = new T size;/动态分配size个T类型的元素空间/析构函数template <class T>Array<T>:Array() delete list;/拷贝构造函数template <class T>Array<T>:Array(const Array<T> &a) /从对象x取得数组大小,并赋值
12、给当前对象的成员size = a.size;/为对象申请内存并进行出错检查list = new Tsize;/ 动态分配n个T类型的元素空间/从对象X复制数组元素到本对象 for (int i = 0; i < size; i+)listi = a.listi;/重载"="运算符,将对象rhs赋值给本对象。实现对象之间的整体赋值template <class T>Array<T> &Array<T>:operator = (const Array<T>& rhs) if (&rhs != this
13、) /如果本对象中数组大小与rhs不同,则删除数组原有内存,然后重新分配if (size != rhs.size) delete list;/删除数组原有内存size = rhs.size;/设置本对象的数组大小list = new Tsize;/重新分配n个元素的内存/从对象X复制数组元素到本对象 for (int i = 0; i < size; i+)listi = rhs.listi;return *this;/返回当前对象的引用/重载下标运算符,实现与普通数组一样通过下标访问元素,并且具有越界检查功能template <class T>T &Array<
14、;T>:operator (int n) assert(n >= 0 && n < size);/检查下标是否越界return listn;/返回下标为n的数组元素template <class T>const T &Array<T>:operator (int n) const assert(n >= 0 && n < size);/检查下标是否越界return listn;/返回下标为n的数组元素/重载指针转换运算符,将Array类的对象名转换为T类型的指针,/指向当前对象中的私有数组。/因而可以
15、象使用普通数组首地址一样使用Array类的对象名template <class T>Array<T>:operator T * () return list;/返回当前对象中私有数组的首地址template <class T>Array<T>:operator const T * () const return list;/返回当前对象中私有数组的首地址/取当前数组的大小template <class T>int Array<T>:getSize() const return size;/ 将数组大小修改为sztempla
16、te <class T>void Array<T>:resize(int sz) assert(sz >= 0);/检查sz是否非负if (sz = size)/如果指定的大小与原有大小一样,什么也不做return;T* newList = new T sz;/申请新的数组内存int n = (sz < size) ? sz : size;/将sz与size中较小的一个赋值给n/将原有数组中前n个元素复制到新数组中for (int i = 0; i < n; i+)newListi = listi;delete list;/删除原数组list = ne
17、wList;/ 使list指向新数组size = sz;/更新size#endif /ARRAY_H/9_4.cpp#include <iostream>#include <iomanip>#include "Array.h"using namespace std;int main() Array<int> a(10);/ 用来存放质数的数组,初始状态有10个元素。int count = 0;int n;cout << "Enter a value >= 2 as upper limit for prime n
18、umbers: "cin >> n;for (int i = 2; i <= n; i+) /检查i是否能被比它小的质数整除bool isPrime = true;for (int j = 0; j < count; j+)if (i % aj = 0) /若i被aj整除,说明i不是质数isPrime = false;break;/把i写入质数表中if (isPrime) /如果质数表满了,将其空间加倍if (count = a.getSize()a.resize(count * 2);acount+ = i;for (int i = 0; i < co
19、unt; i+)/输出质数cout << setw(8) << ai;cout << endl;return 0;9_5链表类应用案例/Node.h#ifndef NODE_H#define NODE_H/类模板的定义template <class T>class Node private:Node<T> *next;/指向后继结点的指针public:T data;/数据域Node (const T &data, Node<T> *next = 0); /构造函数void insertAfter(Node<T
20、> *p);/在本结点之后插入一个同类结点p Node<T> *deleteAfter();/删除本结点的后继结点,并返回其地址Node<T> *nextNode(); /获取后继结点的地址const Node<T> *nextNode() const; /获取后继结点的地址;/类的实现部分/构造函数,初始化数据和指针成员template <class T>Node<T>:Node(const T& data, Node<T> *next/* = 0 */) : data(data), next(next)
21、/返回后继结点的指针template <class T>Node<T> *Node<T>:nextNode() return next;/返回后继结点的指针template <class T>const Node<T> *Node<T>:nextNode() const return next; /在当前结点之后插入一个结点p template <class T>void Node<T>:insertAfter(Node<T> *p) p->next = next;/p结点指针域指
22、向当前结点的后继结点 next = p;/当前结点的指针域指向p /删除当前结点的后继结点,并返回其地址template <class T>Node<T> *Node<T>:deleteAfter() Node<T> *tempPtr = next;/将欲删除的结点地址存储到tempPtr中if (next = 0)/如果当前结点没有后继结点,则返回空指针return 0;next = tempPtr->next;/使当前结点的指针域指向tempPtr的后继结点return tempPtr;/返回被删除的结点的地址#endif /NODE_
23、H/ LinkedList.h#ifndef LINKEDLIST_H#define LINKEDLIST_H#include "Node.h"template <class T>class LinkedList private:/数据成员:Node<T> *front, *rear;/表头和表尾指针Node<T> *prevPtr, *currPtr; /记录表当前遍历位置的指针,由插入和删除操作更新int size;/表中的元素个数int position;/当前元素在表中的位置序号。由函数reset使用/函数成员:/生成新结点,数据
24、域为item,指针域为ptrNextNode<T> *newNode(const T &item,Node<T> *ptrNext=NULL);/释放结点void freeNode(Node<T> *p);/将链表L 拷贝到当前表(假设当前表为空)。/被拷贝构造函数、operator = 调用void copy(const LinkedList<T>& L);public:LinkedList();/构造函数LinkedList(const LinkedList<T> &L); /拷贝构造函数LinkedLis
25、t();/析构函数LinkedList<T> & operator = (const LinkedList<T> &L); /重载赋值运算符int getSize() const;/返回链表中元素个数bool isEmpty() const;/链表是否为空void reset(int pos = 0);/初始化游标的位置void next();/使游标移动到下一个结点bool endOfList() const;/游标是否到了链尾int currentPosition(void) const;/返回游标当前的位置void insertFront(cons
26、t T &item);/在表头插入结点void insertRear(const T &item);/在表尾添加结点void insertAt(const T &item);/在当前结点之前插入结点void insertAfter(const T &item);/在当前结点之后插入结点T deleteFront();/删除头结点void deleteCurrent();/删除当前结点T& data();/返回对当前结点成员数据的引用const T& data() const; /返回对当前结点成员数据的常引用/清空链表:释放所有结点的内存空间。被
27、析构函数、operator= 调用void clear();#endif /LINKEDLIST_H/9_7.cpp#include <iostream>#include "LinkedList.h"using namespace std;int main() LinkedList<int> list;/输入10个整数依次向表头插入for (int i = 0; i < 10; i+) int item;cin >> item;list.insertFront(item);/输出链表cout << "List:
28、 "list.reset();/输出各结点数据,直到链表尾while (!list.endOfList() cout << list.data() << " "list.next();/使游标指向下一个结点cout << endl;/输入需要删除的整数int key;cout << "Please enter some integer needed to be deleted: "cin >> key;/查找并删除结点list.reset();while (!list.endOfLis
29、t() if (list.data() = key) list.deleteCurrent();list.next();/输出链表cout << "List: "list.reset();/输出各结点数据,直到链表尾while (!list.endOfList() cout << list.data() << " "list.next(); /使游标指向下一个结点cout << endl;return 0;9_6栈的应用(一个简单的整数计算器)/Stack.h#ifndef STACK_H#define S
30、TACK_H#include <cassert> /模板的定义,SIZE为栈的大小template <class T, int SIZE = 50>class Stack private:T listSIZE;/数组,用于存放栈的元素int top;/栈顶位置(数组下标)public:Stack();/构造函数,初始化栈void push(const T &item);/将元素item压入栈T pop();/将栈顶元素弹出栈void clear();/将栈清空const T &peek() const;/访问栈顶元素bool isEmpty() cons
31、t;/测试是否栈满bool isFull() const;/测试是否栈空;/模板的实现template <class T, int SIZE>Stack<T, SIZE>:Stack() : top(-1) /构造函数,栈顶初始化为-1template <class T, int SIZE>void Stack<T, SIZE>:push(const T &item) /将元素item压入栈assert(!isFull();/如果栈满了,则报错list+top = item;/将新元素压入栈顶template <class T, i
32、nt SIZE>T Stack<T, SIZE>:pop() /将栈顶元素弹出栈assert(!isEmpty();/如果栈为空,则报错return listtop-;/返回栈顶元素,并将其弹出栈顶template <class T, int SIZE>const T &Stack<T, SIZE>:peek() const /访问栈顶元素assert(!isEmpty();/如果栈为空,则报错return listtop;/返回栈顶元素template <class T, int SIZE>bool Stack<T, SIZ
33、E>:isEmpty() const /测试栈是否空return top = -1;template <class T, int SIZE>bool Stack<T, SIZE>:isFull() const /测试是否栈满return top = SIZE - 1;template <class T, int SIZE>void Stack<T, SIZE>:clear() /清空栈top = -1;#endif/STACK_H/Calculator.h#ifndef CALCULATOR_H#define CALCULATOR_H#in
34、clude "Stack.h"/ 包含栈类模板定义文件class Calculator /计算器类private:Stack<double> s;/ 操作数栈void enter(double num);/将操作数num压入栈/连续将两个操作数弹出栈,放在opnd1和opnd2中bool getTwoOperands(double &opnd1, double &opnd2);void compute(char op);/执行由操作符op指定的运算public:void run();/运行计算器程序void clear();/清空操作数栈;#en
35、dif /CALCULATOR_H#include "Calculator.h"#include <iostream>#include <sstream>#include <cmath>using namespace std;void Calculator:enter(double num) /将操作数num压入栈s.push(num);/连续将两个操作数弹出栈,放在opnd1和opnd2中/如果栈中没有两个操作数,则返回False 并输出相关信息bool Calculator:getTwoOperands(double &opn
36、d1, double &opnd2) if (s.isEmpty() /检查栈是否空cerr << "Missing operand!" << endl;return false;opnd1 = s.pop();/将右操作数弹出栈if (s.isEmpty() /检查栈是否空cerr << "Missing operand!" << endl;return false;opnd2 = s.pop();/将左操作数弹出栈return true;void Calculator:compute(char
37、op) /执行运算double operand1, operand2;bool result = getTwoOperands(operand1, operand2); /将两个操作数弹出栈if (result) /如果成功,执行运算并将运算结果压入栈switch(op) case '+':s.push(operand2 + operand1);break;case '-':s.push(operand2 - operand1);break;case '*':s.push(operand2 * operand1);break;case '
38、/':if (operand1 = 0) /检查除数是否为0cerr << "Divided by 0!" << endl;s.clear();/除数为0时清空栈 elses.push(operand2 / operand1);break;case '':s.push(pow(operand2, operand1);break;default:cerr << "Unrecognized operator!" << endl;break;cout << "= &q
39、uot; << s.peek() << " "/输出本次运算结果 elses.clear();/操作数不够,清空栈/工具函数,用于将字符串转换为实数inline double stringToDouble(const string &str) istringstream stream(str);/字符串输入流double result;stream >> result;return result;void Calculator:run() /读入并处理后缀表达式string str;while (cin >> str,
40、 str != "q") switch(str0) case 'c':s.clear();/遇'c'清空操作数栈break;case '-':/遇'-'需判断是减号还是负号if (str.size() > 1)/若字符串长度>1,说明读到的是负数的负号enter(stringToDouble(str);/将字符串转换为整数,压入栈elsecompute(str0);/若是减号则执行计算break;case '+':/遇到其它操作符时case '*':case '
41、;/':case '':compute(str0);/执行计算break;default:/若读入的是操作数,转换为整型后压入栈enter(stringToDouble(str);break;void Calculator:clear() /清空操作数栈s.clear(); /9_9.cpp#include "Calculator.h"int main() Calculator c;c.run();return 0;9_7队列类模板举例/Queue.h#ifndef QUEUE_H#define QUEUE_H#include <cassert
42、>/类模板的定义template <class T, int SIZE = 50>class Queue private:int front, rear, count;/队头指针、队尾指针、元素个数T listSIZE;/队列元素数组public:Queue(); /构造函数,初始化队头指针、队尾指针、元素个数void insert(const T &item);/新元素入队T remove();/元素出队void clear();/清空队列const T &getFront() const;/访问队首元素/测试队列状态int getLength() cons
43、t;/求队列长度(元素个数)bool isEmpty() const;/判队队列空否bool isFull() const;/判断队列满否;/构造函数,初始化队头指针、队尾指针、元素个数template <class T, int SIZE>Queue<T, SIZE>:Queue() : front(0), rear(0), count(0) template <class T, int SIZE>void Queue<T, SIZE>:insert (const T& item) /向队尾插入元素(入队)assert(count !=
44、 SIZE);count+;/元素个数增1listrear = item;/向队尾插入元素rear = (rear + 1) % SIZE;/队尾指针增1,用取余运算实现循环队列template <class T, int SIZE>T Queue<T, SIZE>:remove() /删除队首元素,并返回该元素的值(出队)assert(count != 0);int temp = front;/记录下原先的队首指针 count-;/元素个数自减 front = (front + 1) % SIZE;/队首指针增1。取余以实现循环队列 return listtemp;/
45、返回首元素值template <class T, int SIZE>const T &Queue<T, SIZE>:getFront() const /访问队列首元素(返回其值)return listfront;template <class T, int SIZE>int Queue<T, SIZE>:getLength() const /返回队列元素个数return count;template <class T, int SIZE>bool Queue<T, SIZE>:isEmpty() const /测试
46、队空否return count = 0;template <class T, int SIZE>bool Queue<T, SIZE>:isFull() const /测试队满否return count = SIZE;template <class T, int SIZE>void Queue<T, SIZE>:clear() /清空队列count = 0;front = 0; rear = 0; #endif /QUEUE_H9_8直接插入排序函数模板/9_11.h#ifndef HEADER_9_11_H#define HEADER_9_11
47、_H/用直接插入排序法对数组A中的元素进行升序排列template <class T>void insertionSort(T a, int n) int i, j;T temp;/将下标为1n-1的元素逐个插入到已排序序列中适当的位置for (int i = 1; i < n; i+) /从ai - 1开始向a0方向扫描各元素,寻找适当位置插入aiint j = i;T temp = ai;while (j > 0 && temp < aj - 1) /逐个比较,直到temp >= aj - 1时,j便是应插入的位置。/若达到j = 0,则
48、0是应插入的位置。aj = aj - 1; /将元素逐个后移,以便找到插入位置时可立即插入。j-;/插入位置已找到,立即插入。aj = temp;#endif/HEADER_9_11_H9_9直接选择排序函数模板/9_12.h#ifndef HEADER_9_12_H#define HEADER_9_12_H/辅助函数:交换x和y的值template <class T>void mySwap(T &x, T &y) T temp = x;x = y;y = temp;/用选择法对数组a的n个元素进行排序template <class T>void selectionSort(T a, in
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025试论《中华人民共和国国际货物销售合同公约》中的价格条款
- 2025建筑改建合同样本
- 2025年度物料供应合同
- 2025茶叶购销合同书协议模板
- 2025墙面修补维护合同
- 2025居间服务合同样本
- 2025年铜基、镍基钎料合作协议书
- 2025共同租赁商业空间合同
- 2025电子产品制造承包合同范本
- 2025产权合同先进技术许可合同
- (2024年)面神经炎课件完整版
- 减盐减油健康教育教案反思
- 特斯拉国产供应链研究报告
- 如何进行医疗垃圾的安全运输
- 公共停车场建设项目可行性研究报告
- 保安服务标准及工作流程
- 2024年中考数学几何模型归纳(全国通用):18 全等与相似模型之十字模型(学生版)
- 外科疾病分级目录
- 国家级教学成果的培育提炼与申报
- 海南师范大学《高等数学》2020-2021期末试卷B
- 2023年09月黑龙江省大兴安岭地区“黑龙江人才周”校园引才活动引进90名人员笔试历年难易错点考题荟萃附带答案详解
评论
0/150
提交评论