C++程序设计大作业2.doc_第1页
C++程序设计大作业2.doc_第2页
C++程序设计大作业2.doc_第3页
C++程序设计大作业2.doc_第4页
C++程序设计大作业2.doc_第5页
已阅读5页,还剩10页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

程序设计基础大作业姓 名:学 号:班 级:成 绩:信息科学与工程学院2009年7月5日程序设计基础大作业1.矩阵的综合运算1.1.需求陈述此程序为设计一套C函数库用于矩阵的计算,实现矩阵的各种计算功能,同时把矩阵的行列和矩阵的元素封装在一起,使关于矩阵的各种信息更加方便被用户运用。1.2.需求分析函数功能需求:项目功能子功能备注Matrix初始化矩阵的初始化initMatrix()矩阵的具体定义为:typedef struct size_t line;size_t row;int elMAX_MATRIXMAX_MATRIX; Matrix;初始化为单位矩阵Identity()从文件输入readMatrix()和向文件输出writeMatrix()矩阵运算判断矩阵是否为空:isEmptyMatrix()矩阵加法addMatrix矩阵乘法multiMatrix()求逆矩阵inverseMatrix()求矩阵的转置transMatrix()求矩阵行列式的值数据需求:为提高计算准确性和节约时间,故提前在文件中录入数据,矩阵计算时大多直接调用。1.3. 程序设计思想1.3.1 数据类型矩阵采用静态的二维整型数组来表示,将矩阵的行数、列数和二维数组封装在一个结构体中。矩阵的上限可用符号常量“MAX_MATRIX”来表示,实际的行和列的项数由结构体中表示行和列的数据项控制。矩阵的具体定义为:#define MAX_MATRIX 100typedef size_t line; /矩阵的行数size_t row; /矩阵的行数int elMAX_MATRIXMAX_MATRIX;/矩阵元素 Matrix;1.3.2 功能分析a) 矩阵的初始化Matrix initMatrix(int *a, size_t m, size_t n)功能:用一个m行n列的二维数组a来初始化一个矩阵,把行列和元素封装在一起,该矩阵的值作为返回值,返回值的类型为一个结构体类型。实现思路:矩阵的行数初始化为二维数组的行数,矩阵的列数初始化为二维数组的列数,矩阵的元素初始化为二维数组的元素。返回初始化后的矩阵。b) 初始化为单位矩阵Matrix Identity(size_t m);功能:创建一个m行m列的单位矩阵,矩阵的值作为返回值,返回值的类型为一个结构体类型。实现思路:矩阵的行和列初始化为相同值,矩阵的对角线元素初始化为1,其余元素初始化为0。返回初始化后的矩阵。c) 判断矩阵是否为空:size_t isEmptyMatrix(Matrix a);功能:判断一个矩阵a是否为空,是指某个matrix型变量内是否有数据,即是否已经存储了矩阵;返回值用来表示矩阵的元素个数:矩阵为空则返回0,否则返回矩阵元素个数。实现思路:若矩阵为空,则行列数为0,否则为非0,故可直接返回矩阵的行和列的乘积a-line*a-row。d) 从文件输入int readMatrix(Matrix *a, size_t m, size_t n, FILE *fp);和向文件输出int writeMatrix(Matrix *a, FILE *fp);功能:从文件fp中读取一个m行n列的矩阵,存入指针a所指示的存储空间内;向文件fp写入指针a所指示的存储空间内的矩阵;返回值均为实际读出(写入)的矩阵元素数目、若不能读或写则返回0。实现思路:从文件读出矩阵时,打开文件,不能读时返回0,否则读出m*n个元素,矩阵的行为m,矩阵的列为n。向文件写入矩阵时,不能写返回0,否则向文件写入m*n个元素,每n个为一行,共m行。e) 矩阵加法Matrix *addMatrix(Matrix *a, Matrix *b)矩阵乘法Matrix *multiMatrix(Matrix *a, Matrix *b)功能:把指针a所指示的存储空间内的矩阵与指针b所指示的存储空间内的矩阵向加(相乘),结果放入a所指示的存储空间内,返回值为存储结果的地址。实现思路:实现矩阵的加法时,若两矩阵为空矩阵或对应行列不相等,则不能相加,返回空指针NULL,否则,对应元素相加,结果放入a中,返回a;实现矩阵的乘法时,若两矩阵为空矩阵或a的列数和b的行数不相等,则不能相乘,返回空指针NULL,否则,a的行数为乘积矩阵的行数,b的列数为乘积矩阵的列数,a的第i行和b的第j列的对应元素的乘积的和为乘积矩阵的i行j列的元素。乘积放入a中,返回乘积矩阵的地址a。关键代码:/*a的第i行和b的第j列的对应元素的乘积的和为乘积矩阵的i行j列的元素*/for(int i=0;ic.line;i+) for(int j=0;jc.row;j+) c.elij=0; for(int k=0;krow;k+) c.elij+=a-elik*b-elkj; f) 求矩阵的转置Matrix transMatrix(Matrix *a)功能:求矩阵a的转置,返回转置矩阵。实现思路:把a的元素关于对角线互换,返回转置矩阵。g) 求行列式的值double HANGLIESHI(Matrix a)功能:在能求行列式的值时,计算行列式的之值并返回结果。实现思路:若矩阵为空矩阵或矩阵不是方阵,则不能求行列式的值,返回0。若矩阵只有一个元素,行列式的值就是该元素的值。否则运用递归方法,把行列式按行展开,求每个元素的代数余子式和该元素的积,在求和,即为行列式的值。关键代码:/*去掉第1行第j列,求其余子式*/if(tch);/释放内存空间 s-len=0;/长度赋值为0b) 初始化为空串Str initNullString()、判断是否为空串并求字符串长度size_t isNullString(Str *s)功能:初始化为空串,初始化成一个空字符串。判断是否为空串并求字符串长度,为进行字符串操作,先判断字符串是否为空。实现思路:初始化为空串,把Str类型的结构体成员(字符串和长度)都赋值为0。判断是否为空串并求字符串长度,若结构体成员中字符串长度为0,则字符串为空,否则不为空,返回字符串的长度值。关键代码:/*长度和内容都为空*/empty.len=0;empty.ch=0;c) 字符串比较int StringCmp(Str *s1, Str *s2)、字符串拷贝Str *StringCpy (Str *s1, Str *s2)、字符串连接Str *StringCat (Str *s1, Str *s2)功能:字符串比较,实现两个字符串的比较,返回比较大小值;字符串拷贝,把s2的字符串拷贝到s1中,返回拷贝后的字符串地址;字符串连接,把s2的字符串连接到s1的后面,返回连接后的字符串的地址。实现思路:字符串比较,用库函数比较;字符串拷贝,弱s1的字符串的长度小于s2,需重新给s1分配内存空间,然后用库函数把s2拷贝到s1中;字符串连接,连接后的字符串的长度大于s1,故需给s1重新分配内存空间,用库函数把s2连接到s1后面。关键代码:/*s1的存储空间不够,需重新开辟空间*/if(s1-lenlen) StringDes(s1);/释放原来空间 s1-ch=(char *)malloc( sizeof(char)*(s2-len+1);/重新开辟空间/*字符串的连接,s1内存不够,需重新开辟空间*/StringDes(s1);/释放原来空间s1-ch=(char*)malloc( sizeof(char)*(s1-len+s2-len+1);/重新开辟d) 取字符在串中第一次出现的位置char *StringChr(Str *s1, char c) 取字符在串中最后一次出现的位置char *StringrChr(Str *s1, char c)取子串在串中第一次出现的位置char *StringStrr(Str *s1, Str *s2)功能:查找字符或字符串在另一字符串中出现的位置,返回值为找到的地址。实现思路:直接用c语言库函数查找。e) 字符串的前n个字符的比较int StringnCmp(Str *s1, Str *s2,size_t n)、字符串的前n个字符的拷贝char *StringnCpy(Str *s1, Str *s2,size_t n)功能:字符串的前n个字符的比较,实现两个字符串钱n个字符之间的比较,返回比较结果。字符串的前n个字符的拷贝,实现两个字符串前n个字符之间的拷贝,返回拷贝结果的地址。实现思路:字符串的前n个字符的比较,直接用c语言库函数比较两字符串的前n个字符,返回比较大小。字符串的前n个字符的拷贝,若s1中字符串测长度小于s2,需给s1重新分配内存空间,再用c语言库函数实现前n个字符的拷贝,返回拷贝结果的地址。关键代码:/*若s1的长度小于n,需重新分配空间*/if(s1-len ch=(char *)malloc( sizeof(char)*n);/重新开辟空间f) 去字符串中常见的控制符size_t StringTrim(Str *s)功能:把字符串s中常见的文本占位符:回车(“n”值13)、换行(“r”值10、也叫软回车)、走纸符(“f”值12)、水平制表符(“t”值9)、垂直制表符(“v”值9)、空格(“ ”值32)。返回值为修改后s的长度。实现思路:一次从第一个字符开始查找,若第i个字符为控制符,查找后面的字符,若不为控制符,赋值给第i个字符。字符串的长度为新字符串的长度,并返回长度值。关键代码:for(i=0;ilen+1;i+)/*若第i个字符为控制符,查找第i个字符之后第一个不为控制符的字符*/ if(isspace(s-chi)!=0) for(t=i;tlen+1;t+) /*找到后赋值给第i个字符*/ if(isspace(s-cht)=0) s-chi+=s-cht; g) 字符串的文件输入输出size_t fgetSring(Str *s, int n, FILE *stream) 、size_t fputSring(Str *s, FILE *stream)功能:fputSring()把s中的字符串内容输出到文件流stream中,fgetSring从文件流stream中读取长度不超过n的字符,放入字符串s中。返回值意为实际读取或写入的字符串长度。实现思路:打开文件,若不能读或写,返回0,否则,从文件读出字符串初始化为Str型,返回读取的字符串的长度;把字符串写入文件,返回写入的字符串的长度。h) 字符串的字符终端界面的标准输入输出char* getSring(Str *s, int n)、 size_t fputSring(Str *s, FILE *stream)功能:从屏幕输入字符串和把字符串输出到屏幕,返回字符串的长度值。3.动态双向链表的操作3.1.需求陈述:设计一套C函数库用于动态双向循环链表的操作,同时把链表的结点数和链表的数据内容串封装在一起,使关于链表的各种信息更加方便被用户运用。3.2.需求分析:函数功能需求:项目功能子功能备注LinkList基本功能创建结点creat_node()/* 链表结点中存储的数据的类型:LNodeT */typedef int LNodeT;/* 链表结点的数据类型的预先声明 */struct linklist;/* 双向链表结点的数据类型,两部分:data为数据、next指向下一结点的地址,pre指向上一个结点的地址 */struct linklist LNodeT data;struct linklist *next;struct linklist *pre;字符串的销毁erase_node()头部插入insert_first()尾部追加insert_tail()头部删除delete_first()尾部删除delete_tail()按数据内容在链表中插入结点insert_by_data()按顺序在链表中插入结点insert_by_sub()获取链表的长度linklen()按数据内容匹配结点travel_bydata()按下标访问链表trabel_byseq()数据需求:为提高计算准确性和节约时间,故提前在主函数中录入,链表操作时大多直接调用。3.3. 程序设计思想3.3.1 数据类型链表结点中存储的数据的类型为LNodeT,这里先定义为int类型。typedef int LNodeT;双向循环链表结点的数据类型包括两部分:data为数据、next和pre为向前和向后指针、分别用来存储前一结点和后一结点的地址。struct linklist LNodeT data;struct linklist *next; /*向后的指针*/struct linklist *pre; /*向前的指针*/;定义链表的数据类型LinkT,链表里每个结点都采用动态的内存分配。typedef struct linklist LinkT;3.3.2 功能分析a) 创建结点LinkT* creat_node(LNodeT a)、字符串的销毁#define erase_node(p) ( free(p) )功能:creat_node()用来初始化一个结点,在这个函数里为结点分配内存空间,所以要用一个LNodeT类型的参数把结点数据传进来;返回一个链表结点的指针LinkT*,把访问存储空间的首地址传出去。 erase_node()用来释放一个链表的结点,它需要一个结点的存储位置。实现思路:首先为新结点开辟内存空间,然后把数据赋值给新节点,把向前和向后的指针赋值为空,返回该结点的地址。关键代码:LinkT *p=(LinkT*)malloc(sizeof(LinkT);/为新节点开辟空间p-next=NULL;/把向后的指针赋值为空p-pre=NULL;/把向前的指针赋值为空b) 头部插入LinkT* insert_first(LinkT *head, LinkT *p)LinkT* insert_first1(LinkT *head, LNodeT a)尾部追加LinkT* insert_tail(LinkT *head, LinkT *p)功能:在链表的头部和尾部分别插入一个结点,返回新链表的头指针。实现思路:头部插入:若原链表为空,新链表只有一个结点,向前和向后的指针指向本身。否则,新结点的向前的指针指向原链表的尾,向后的指针指向原链表的第一个结点,head指向新结点,插入新结点。若根据结点的数据内容插入,需先创建结点。尾部追加:若原链表为空,新链表只有一个结点,相当于在头部插入,否则,相当于先在头部插入,再把head向后移动一个位置。关键代码: 1 头部插入中if(!head)/此时原链表为空链表,插入后只有一个结点p-next=p;p-pre=p;head=p;elsep-pre=head-pre;/p的前一个结点指向原链表尾p-next=head;/p的后一个结点指向原链表头head-pre-next=p;/原链表尾的下一个结点指向phead-pre=p;/原链表头的上一个结点指向phead=p;/链表头改变2 尾部追加中if(!head)/原链表为空,相当于在头部插入一个结点 head= insert_first(head,p);else/*相当于先在头部插入,再把head向后移动一个位置*/ q=insert_first(head,p); head=q-next;c) 头部删除LinkT* delete_first(LinkT *head)、尾部删除LinkT* delete_tail(LinkT *head)功能:在链表的头部和尾部分别删除一个结点,返回新链表的头指针。实现思路:头部删除:链表为空,不用删除,若有一个结点,删除该结点,新链表为空。否则,head后移一个位置,原来的head结点释放掉。尾部删除:链表为空,不用删除,否则,相当于head向前移动一个位置,删除头结点。关键代码:1 头部删除中 else if(head-next=head)/只有一个结点,删除该结点 erase_node(head);/释放结点 head=NULL;/此时新链表为空 else /*把头结点删除,并释放掉,head向后移动一个位置*/ p=head-next; head-pre-next=p; p-pre=head-pre; erase_node(head);/释放结点 head=p; 2 尾部删除中 else /*相当于head向前移动一个位置,删除头结点*/ head=q; head-next=p; p-pre=head; q-pre-next=head; return delete_first(head);/返回删除结点后的头指针 d) 按数据内容在链表中插入结点LinkT* insert_by_data(LinkT *head,LNodeT node) 按顺序在链表中插入结点LinkT* insert_by_sub(LinkT *head, LinkT *p,int n)功能:实现在链表中插入新结点,返回插入结点后的头指针。实现思路:按数据内容在链表中插入结点:先把数据内容初始化为结点,若链表为空,相当于在头部插入,若第一个结点数据大于node,相当于在头部插入,否则,查找第一个大于node的结点,把新结点插入到该结点前面,没有找到,把新结点插入到尾部。按顺序在链表中插入结点:链表为空,相当于在尾部插入,若输入顺序值超过链表长度,不插入。若n=1相当于在头部插入,否则,遍历链表,找到第n个位置,插入结点。关键代码:1 按数据内容插入 LinkT *q,*p=creat_node(node);/先把数据内容初始化为结点 if(head=NULL | head-data node)/链表为空,相当于在头部插 head=insert_first(head,p); else /*查找第一个大于node的结点,把新结点插入到该结点前面*/ for(q=head-next; q-data next); if(q=head)/没有找到,把新结点插入到尾部 head=insert_tail(head,p);2 按顺序插入 if(!head| n=1)/相当于在头部插入 head=insert_first(head,p); else /*遍历链表,找到第n个位置,插入结点到 q 的前面*/ for(i=2,q=head-next;inext); if(q=head)/如果结点数小于n,插入到尾部 head=insert_tail(head,p);e) 获取链表的长度size_t linklen(LinkT *head)功能:获取链表的长度实现思路:若链表为空,返回0,否则依次找到不为head的结点,找出结点的数目,并返回该值。关键代码:if(head=NULL) return 0;/链表为空,返回0/*不为空,依次找到不为head的结点,找出结点的数目*/while(p-next!=head) p=p-next; n+;f) 链表的遍历:按数据内容匹配结点LinkT* travel_bydata(LNodeT* a, LinkT* head)、按下标访问链表LinkT* travel_byseq(LNodeT* a, LinkT* head, size_t n)功能:travel_bydata()跟距a指向的结点的数据内容来匹配链表head中的结点,把匹配到的结点地址传出去。travel_byseq()使得链表可以向数组一样依下标访问,虽然没有那么快。它这倒head中的第n个结点,把该结点的内容复制到a所指的内存之中,并把第n个结点的地址传出去。实现思路:按数据内容匹配结点:若链表为空,返回空指针,第一个满足,返回头指针,否则遍历链表,查找满足的结点,返回该结点的指针,若没有找到,返回空指针。按下标访问链表:链表为空,返回空指针,第一个满足,把数据赋值给*a,返回头指针,否则找到第n个结点,把数据赋值给*a,返回该结点的地址,若没有找到,返回空指针。关键代码:1 按数据内容匹配结点中 if(head=NULL)/链表为空,返回空指针 return NULL; else if(head-data=*a)/第一个满足,返回头指针 return head; else /*遍历链表,查找满足的结点,返回该结点的指针*/ p=head-next; for(p=head-next;p-data!=*a & p!=head;p=p-next);2 按下标访问链表 else if(head=NULL)/链表为空,返回空指针 return NULL; else if(n=1)/第一个满足返回头指针 *a=head-data;/把数据赋值给*a else /*找到第n个结点,把数据赋值给*a,返回该结点的地址*/ for(i=2,p=head-next;inext); if(p=head)/若没有找到,返回空指针 return NULL;g) 链表的输出void outputLinkT(LinkT *head)功能:输出链表的各结点的数据。实现思路:先输出第一个结点的数据,依次输出后面结点的数据,到head停止。测试数据及结果:141.矩阵的综合运算1.初始化矩阵成m行n列2.初始化m阶单位阵3.判断矩阵是否为空4.矩阵加法5.矩阵乘法6行列式的值7.矩阵的逆8.矩阵转置0.退出What do you choose?1初始化为行列数:m,n1,11.000写入文件元素个数为:1请按任意键继续. . .2.初始化单位阵阶数:m21.000 0.0000.000 1.0003.1读入矩阵为:元素个数为:0,是空矩阵3.2读入矩阵为:1.0002.000元素个数为:2,不是空矩阵4.1读入矩阵为:1.000 2.000读入矩阵为:1.000不能相加!4.2读入矩阵为:1.000 2.000读入矩阵为:1.000 2.000结果为:2.000 4.0005.1读入矩阵为:1.000 2.0003.000 4.000读入矩阵为:1.000 2.000不能相乘!5.2读入矩阵为:1.0002.000读入矩阵为:1.000 2.000结果为:1.000 2.0002.000 4.0006.读入矩阵为:1.000 2.0003.000 4.000行列式的值为:-2.0007.1读入矩阵为:1.000 2.0003.000 4.0005.000 6.000矩阵不能求逆!7.2读入矩阵为:1.000 2.0003.000 4.000结果为:-2.000 1.0001.500 -0.5008.读入矩阵为:1.000 2.0003.000 4.0005.000 6.000结果为:1.000 3.000 5.000 2.000 4.000 6.0002. 字符串操作1.字符串的初始化2.初始化为空串3.判断是否为空串并求字符串长度4.字符串比较、字符串拷贝、字符串连接5.取字符在串中第一次出现的位置 最后一次出现的位置 取子串在串中第一次出现的位置6.字符串的前n个字符的比较 字符串的前n个字符的拷贝7.去字符串中常见的控制符What do you choose?1Hello world.长度为:122.长度:0字符串:(null)3.1.读入字符个数为0读入字符串为:是空串!3.2. 读入字符个数为3读入字符串为:no不是空串! 长度为:24.读入字符串为:no pqr读入字符串为:no比较结果:1拷贝结果 str1:nobefor stringcat str2:no连接结果:nono5.1.读入字符串为:no pqrno读入字符串为:no字符c在串中第一次出现的位置 (null)字符c在串中最后一次出现的位置 (null)子串str2在串str1中第一次出现的位置: no pqrno5.2. 读入字符串为:no pqrnos读入字符串为:no字符o在串中第一次出现的位置 o pqrnos字符o在串中最后一次出现的位置 os子串str2在串str1中第一次出现的位置:no pqrnos6.Hello world.my assignment.前3个字符比较结果:-1前3个字符拷贝结果:my lo world.

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论