矩阵操作C++.doc_第1页
矩阵操作C++.doc_第2页
矩阵操作C++.doc_第3页
矩阵操作C++.doc_第4页
矩阵操作C++.doc_第5页
已阅读5页,还剩22页未读 继续免费阅读

下载本文档

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

文档简介

淮 阴 工 学 院算法设计技能训练设计题目: 矩阵操作(动态数组)院 别: 计算机与软件工程学院 专 业: 计算机科学与技术 班 级: XXXXXXXXXX 学生姓名: XXX 学 号: XXXXXXXXXX 指导教师: XXXXXX 2017 年11月算法设计技能训练成绩班 级: 计算机1161 学生姓名: XXX 学 号: 1161301105院 别: 计算机与软件工程学院 算法设计技能训练题目: 矩阵操作(动态数组)序号考核指标每项总分所得分数1平时成绩:思想表现、学习态度、工作作风、出勤率。102答辩成绩:课题难度、工作量大小、任务完成情况。403技能训练报告成绩:内容正确性、完整性、书写规范性。50总分教师签字: 日期: 目 录1 引言11.1课题描述11.2课题意义11.3设计思想12 总体设计22.1总体功能结构22.2类的分析与设计23 详细设计和实现33.1构建m*n的全零矩阵33.2构建n*n的方阵33.3拷贝构造函数(深拷贝)33.4根据一维数组拷贝函数33.5根据二维数组拷贝函数33.6析构函数43.7矩阵转置43.8矩阵信息获取及修改43.9矩阵加法43.10矩阵减法43.11矩阵乘法53.12重载=运算符53.13打印函数54 系统测试64.1主界面64.2创建矩阵64.3矩阵相加84.4矩阵相减94.5矩阵数乘94.6矩阵转置104.6矩阵相乘10结论11致 谢12参 考 文 献13附录14231 引言1.1课题描述设计矩阵操作类算法,并做到可以动态的操作不同类型的数组,矩阵操作包括各种类型的构造函数如直接构造m*n型的全零矩阵或者全零方阵或者根据一维数组二维数组来构造矩阵,然后是析构函数。还需要返回行数列数以及设置某一位置的值和返回某一位置的值,操作类主要包括矩阵的转置、加减乘除和数乘赋值功能还有打印功能1.2课题意义矩阵是线性代数研究的主要对象。矩阵是由来源于某一问题的有关的数据所组成的矩形数表,在对矩阵定义了一些重要的运算并逐渐形成了矩阵的理论体系后,矩阵成为对数学研究即应用非常有效的数学工具,矩阵计算的理论与方法在许多实际问题研究中有着广泛的应用。 将矩阵用代码实现可以大大减少实际计算工作量,使人们在生活研究方面得到很大的便利,省时省力。1.3设计思想本算法主要设计一个Matrix的类来实现矩阵的各种操作。该矩阵操作的数据类型可以自己选择,因为采用了模板,相对的设计时也会稍微繁琐一些。矩阵数据成员主要有矩阵元素的头指针,矩阵行数rowNum,矩阵列数colNum。公有成员函数则要实现各种方式的构造函数如直接构造m*n型的全零矩阵或者全零方阵或者根据一维数组二维数组来构造矩阵。获得矩阵信息的功能如获得矩阵的行数列数获得矩阵某一位置的值打印矩阵等。还有修改矩阵某一位置的值的功能,再接下来是最重要的矩阵的各种操作包括加减乘和数乘还有转置等,这些主要通过重载运算符来实现。2 总体设计2.1总体功能结构2.1.1数据成员包括矩阵类所开辟的空间的头指针item、矩阵行数rowNum、矩阵列数colNum。2.1.2主要功能包括在这里采用C+语言实现一个可动态分配的矩阵类,类中包括一些简单的运算等操作具体要求如下:(1)使用构造函数完成矩阵的初始化赋值(动态内存分配);(2)使用拷贝构造函数完成矩阵复制的深拷贝;(3)使用析构函数完成矩阵动态内存的释放;(4)使用函数实现两个矩阵的和;(5)使用函数实现两个矩阵的差;(6)使用函数实现两个矩阵的积;(7)使用函数求矩阵的数乘;(8)使用函数实现矩阵的转置;(9)编写一个主函数测试上述功能。2.2类的分析与设计根据实验要求,设计Matrix类,头文件主要有,,除了矩阵所开辟的空间的头指针和矩阵行数列数为类的私有成员其余均为类的公有成员。因为用了模板所以实现时要注意格式对应,每个函数在类外定义时记得在前面加一句template ,里面的类型定义如果是要设计矩阵内部元素的都用T来代替,然后返回类型还有形参如果是Matrix的话记得在后面加。3 详细设计和实现3.1构建m*n的全零矩阵构造时注意容错率,当m,n的输出出错时可以进行提醒并重新输入,输入正确行数m和列数n,item开辟一个新的大小为m*n的空间,空间的数据类型因为使用了模板可以根据使用者的要求进行变换。矩阵的所有元素在空间是按行依次线性排列的。通过for循环将所有数据成员赋值为零。3.2构建n*n的方阵构造时注意容错率,当n的输出出错时可以进行提醒并重新输入,输入正确n,item开辟一个新的大小为n*n的空间,空间的数据类型因为使用了模板可以根据使用者的要求进行变换。方阵的所有元素在空间是按行依次线性排列的。通过for循环将所有数据成员赋值为零。3.3拷贝构造函数(深拷贝)这里采用深拷贝,而不是直接复制值的浅拷贝,因为浅拷贝直接复制指针的地址,这样会导致两个矩阵共用一个空间即两个矩阵其实是同一个矩阵,其中一个变了另一个也会跟着变。浅拷贝缺点太多,所以这里采用创建一个新的空间把值全部复制过来的深拷贝。空间的类型因为有模板可以根据需要随意更改。3.4根据一维数组拷贝函数因为矩阵的空间里的数据也是线性排列的,所以只要提供一维数组的行数和列数信息就可以实现把一维数组所包含的矩阵复制到数据成员空间中。item根据类型需要开辟空间,然后通过for循环将数组成员复制过去,最后给数据成员行数和列数值就可以了。3.5根据二维数组拷贝函数因为矩阵最常见的形式是二维数组,所以也需要通过二位数组来构造矩阵,不过一般以二维数组为形参的话数组的第二个纬度一定要先设置好值,这样就无法实现动态的构造各种规模的矩阵。所以这里采用另一种方法,就是数组转化为指针的指针。除了形参为指针的指针,在赋值的时候记得把数组强制转化一下就可以了,这样就可以动态构造任意类型的矩阵了3.6析构函数因为只创建了一个连续的数组空间所以比较简单,直接delete就好了。3.7矩阵转置转置函数主要实现将矩阵的行列进行对换,所以赋值时注意把数据成员的行数和列数对调,这里的操作是返回转置后的对象,所以注意this的使用,赋值时是第i行第j列换成第j行第i列,返回类型是Matrix。3.8矩阵信息获取及修改返回行数列数比较简单,直接return对应值就好了。返回某一矩阵的值则注意位置对应关系,i和j都是从0开始的,所以对应关系是i*colNum+j。加上const是为了防止对原数据造成未知的修改。设置某一位置的值也要注意对应关系,对应关系上面已经分析过了都是一样的为i*colNum+j。虽然加了模板,但是修改时还是只能改成原矩阵的数据类型,模板主要在创建的时候起作用。3.9矩阵加法加法函数这里使用对加法运算符重载的形式,矩阵加法必须两个行列数要相同否则不能相加,所以这里使用if语句进行判断,如果不想等就只返回原矩阵。这里没有开辟新空间所以是对加法运算符前面的那个矩阵的空间进行操作,所以待会用等号运算符后,不仅等号前面的矩阵变了,加法前面的矩阵也会变而且两者是相同的。把每个元素重新设置成相加后的值然后返回就好了,注意位置对应关系不要搞错了就好了。3.10矩阵减法减法函数通过对减法运算符的重载来实现。使用时也要用if语句来判断两个矩阵是否能相减,不能则返回原矩阵。同样的,减法也是在减法运算符的前面的矩阵空间里进行操作,通过for循环将每个对应位置的值算好然后赋值给这个空间的对应位置,因为前面已经有了get()set()等函数所以接下来的操作都会方便很多。同样当用x=y-x时,y也随着变了,而且y的值和x的值是一样的。3.11矩阵乘法3.11.1矩阵间相乘矩阵间的乘法则是要求左边矩阵的列数等于右边矩阵的行数,这样乘积才有意义。所以开始就要用if语句来判断两个矩阵是否符合条件,不符合则输出无法相乘,符合则进行计算。创建的新矩阵行数列数应为相乘后的行列数,然后通过for循环按照矩阵运算的法则进行计算并将得出值赋给对应位置。最后返回该矩阵。3.11.2矩阵的数乘数乘相对来说要简单一些,基本操作和上述都差不多,不用开辟新的矩阵,直接在原矩阵上操作就好了,将所有值都乘以输入的数再放回去就好了,最后返回矩阵。3.12重载=运算符重载=运算符,执行该运算符时要先判断原矩阵是否存在,如果存在就删除掉原矩阵。重新创建一个和后面矩阵行列数对应的矩阵,然后将对应的值赋值过去,然后返回this指针即可。3.13打印函数打印函数要用到格式化输出,所以头文件要包括,用setw()函数来每个输出的数所占的字节数,来达到对齐的目的,经过比较数字还是右对齐比较好看所以使用setiosflags(ios:right)来使输出的数都在所占字节的最右边。每输出一行,用endl换行。4 系统测试4.1主界面图4-2-1该main函数用于测试功能,但在编写过程中遇到了不少问题,还好在于永涛老师的帮助下都解决了。首先我限制了最多只能创建两个矩阵,继续往下创建的话变化的都是第二个矩阵,因为只是简单的实现一下函数的功能。使用456功能时默认是对第一个矩阵使用,所以不用将要使用该功能的矩阵创建在第二个。4.2创建矩阵图4-2-2主界面输入1后会显示这个画面,显示有四种创建数组的方式,这四种方式会在这里一一展示,不过待会的运算操作主要用的是34两种方式。4.2.1m*n的零矩阵图4-2-3图4-2-4输入1后再根据提示输入行数和列数,就可以得到对应的零矩阵4.2.2n*n的零方阵图4-2-5图4-2-6输入2后根据提示输入方阵的维度就可以创建对应的零方阵了。4.2.3一维数组构建矩阵图4-2-7图4-2-8输入1然后再输入3进入一维数组创建矩阵功能,根据提示依次输入矩阵行数和列数,然后从左到右从上到下依次输入就能成功创建该矩阵,并且该矩阵会被打印出来方便检查是否有错。4.2.4二维数组构建矩阵图4-2-9图4-2-10输入1在输入3进入二维数组创建矩阵功能,根据提示依次输入矩阵行数和列数,然后从左到右从上到下依次输入就能成功创建该矩阵,输入后屏幕同样会把该矩阵打印出来方便检查是否有错。4.3矩阵相加这里的相加就用上面34构造出来的矩阵图4-2-114.4矩阵相减因为上面已经执行过相加了,所以矩阵1就变成结果的那个矩阵了图4-2-124.5矩阵数乘图4-2-13图4-2-14输入5后显示要被数乘的矩阵,然后按照提示输入要乘的数,屏幕就会打印出结果了,而且原函数也已经变成数乘后的结果了。4.6矩阵转置该main函数的转置功能是把转置功能打印出来,并没有改变原函数的原值。图4-2-154.6矩阵相乘因为那两个构建的矩阵不符合矩阵相乘的要求,所以要重新构建两个,根据矩阵相乘的规则,第一个矩阵的的列要和第二个矩阵的行相同,输入完两个矩阵后在主界面输入4屏幕就会依次打印出矩阵1和矩阵2还有相乘后的结果并且第一个矩阵会变成相乘后的结果。图4-2-16经测试,函数的功能都能顺利实现。结论矩阵操作需要扎实的c+基础,因为里面涉及到各个方面的操作,同时设计该算法也是对过去知识一次很好的巩固。在这里有好几个个人认为比较重要的点需要注意,第一个是模板,使用了模板无疑加大了代码的难度,但也提高了代码的适用性,可以处理多种类型的数据,使用模板时要注意每个函数前要加template ,然后当要返回的类型或者使用的形参是Matrix类时,后面都要加上,再函数里面开辟新空间时要类型换成T,类似这样的都要注意到,否则一个不小心代码就会发生错误。第二个是动态的创建数组以及将之拷贝到矩阵类中,这里面主要要处理的问题是一般数组定义需要确定的空间,而我们是为了实现动态构造数组,就不能使用那种方法,所以我用指针的方法来构造,因为矩阵的物理储存结构是线性有规律的,所以可以通过指针的位移来进行赋值操作,形参要把指针类型。第三个是main函数里的问题,在实现时发现在对象还未定义前就在下面进行使用是会出现问题的,所以这个时候要把前面的定义换成用指针类new一个对象,在主函数前就先定义好指针,这样才能完成在case语句中写入语句操作还未定义的对象。还有就是用了指针之后操作运算符时都要用指针形式来操作如*a = *a + *b。所以熟悉了二维数组和指针还有类之间的关系,才能完成这次的课程设计。致 谢在这一周的算法技能设计训练里,多亏了于长辉老师和高丽老师的指导还有同学们的帮助,是老师们一丝不苟的工作作风和耐心的讲解,我才能理解算法,并知道自己这一周要做什么怎么做。在这里最要感谢的大一的c+老师于永涛,在我每次遇到困难无法解决时是他一直细心的指导着我,并且每一次都能帮我完美解决。所以这个设计不是我一个人的成果,有了大家的无私帮助,我才能顺利的完成这次的算法设计。参 考 文 献1 郑振杰.C+程序设计 北京:人民邮电出版社,20052 柴欣.C/C+程序设计 河北大学出版社,20023 余苏宁、王明福.C+程序设计 北京:高等教育出版社,20034 吕凤翥.C+语言程序设计(第2版).电子工业出版社,2007.25 李云清、杨庆红、揭安全.数据结构M.人民邮电大学出版社,2004.66 Marshall P. Cline and Greg A. Lomow, C+ FAQs, Addison-Wesley, 19957 Bruce Eckel, Thinking in C+(C+ 编程思想,刘宗田 等译),机械工业出版社,20008 Steve Maguire, Writing Clean Code(编程精粹,姜静波 等译),电子工业出版社,19939 Scott Meyers, Effective C+, Addison-Wesley, 199210 Robert B. Murry, C+ Strategies and Tactics, Addison-Wesley, 199311 Steve Summit, C Programming FAQs, Addison-Wesley, 1996附录#include #include #include using namespace std;template class MatrixT *item; /指向矩阵的第一个元素int rowNum; /矩阵行数int colNum; /矩阵列数public:Matrix(int m, int n); /构建m*n的全零矩阵Matrix(int n); /构建一个n*n的全零方阵Matrix(const Matrix &x); /拷贝构造函数(深拷贝)Matrix(T *items, int m, int n); /根据一维数组拷贝函数Matrix(T *items, int m, int n); /根据二维数组拷贝函数Matrix(); /析构函数 Matrix Trans() const; /将矩阵转置void set(int i, int j, T value); /设置矩阵某一位置值int getRow() const return rowNum; /返回行数int getCol() const return colNum; /返回列数T get(int i, int j) const return itemi*colNum + j; /返回某一位置的值Matrix operator +(const Matrix &m); /两个矩阵相加Matrix operator -(const Matrix &m); /两个矩阵相减Matrix operator *(const Matrix &m); /两个矩阵相乘Matrix operator *(const T f); /矩阵乘以常数Matrix& operator=(const Matrix& m);void print(); /打印矩阵;template Matrix:Matrix(int m, int n)if(m0|n0)cerr矩阵大小不能为负;exit(1);rowNum = m;colNum = n;item = new Tm*n;for(int i=0; im*n; i+)itemi = 0;template Matrix:Matrix(int n)if(n0)cerr矩阵大小不能为负;exit(1);rowNum = n;colNum = n;item = new Tn*n;for(int i=0; in*n; i+)itemi = 0;template Matrix:Matrix(const Matrix &x)rowNum = x.rowNum;colNum = x.colNum;item = new TrowNum*colNum;for(int i=0; irowNum*colNum; i+)itemi = x.itemi;template Matrix:Matrix(T *items, int m, int n)item = new Tm*n;for(int i=0; im*n; i+)itemi = itemsi;rowNum = m;colNum = n;template Matrix:Matrix(T *items, int m, int n)item = new Tm*n;rowNum = m;colNum = n;for(int i=0; im; i+)for(int j=0; jn; j+)itemi*n+j = itemsij;coutendl;template void Matrix:print()for(int i=0; irowNum*colNum; i+)coutsetw(5)setiosflags(ios:right)itemi ;if(i+1)%colNum=0)coutendl;template Matrix:Matrix()delete item;template void Matrix:set(int i, int j, T value)itemi*colNum+j = value;template Matrix Matrix:operator +(const Matrix &m)if (m.colNum != colNum | m.rowNum != rowNum) return *this;Matrix _copy = *this;for (int i = 0; i rowNum; i+)for (int j = 0; j colNum; j+)_copy.set(i, j, get(i, j) + m.get(i, j);return _copy;template Matrix Matrix:operator -(const Matrix &m)if (m.colNum != colNum | m.rowNum != rowNum) return *this;Matrix _copy = *this;for (int i = 0; i rowNum; i+)for (int j = 0; j colNum; j+)_copy.set(i, j, get(i, j) - m.get(i, j);return _copy;template Matrix Matrix:operator *(const T f)Matrix _copy = *this;for (int i = 0; i rowNum; i+)for (int j = 0; j colNum; j+)_copy.set(i, j, get(i, j)*f);return _copy;template Matrix Matrix:operator *(const Matrix &m)if (colNum != m.rowNum)cout 无法相乘!;return *this;Matrix _copy(rowNum, m.getCol();for (int i = 0; i rowNum; i+)for (int j = 0; j m.colNum; j+)T sum = 0;for (int k = 0; k m.rowNum; k+)sum += get(i, k)*m.get(k, j);_copy.set(i, j, sum);return _copy;template Matrix& Matrix:operator=(const Matrix & M)colNum = M.colNum;rowNum = M.rowNum;if (item != nullptr) delete item;item = new TcolNum*rowNum;for (int i = 0; i colNum*rowNum; i+)itemi = M.itemi;return *this;template Matrix Matrix:Trans() constMatrix _copy = *this; _copy.rowNum = this-colNum; _copy.colNum = this-rowNum; for (int i = 0; i _copy.rowNum; i+) for (int j = 0; j _copy.colNum; j+) _copy.set(i, j, get(j, i); return _copy;int main()int flag = 0;Matrix *a1, *a2;while (1)int m, n;cout 矩阵操作 endl;cout 1.创建矩阵 endl;cout 2.矩阵相加 endl;cout 3.矩阵相减 endl;cout 4.矩阵相乘 endl;cout 5.矩阵数乘 endl;cout 6.矩阵转置 x;switch (x)case 1:system(cls);cout 1.创建m*n的零矩阵 endl;cout 2.创建n*n的零方阵 endl;cout 3.一维数组创建矩阵 endl;cout 4.二维数组创建矩阵 x;switch (x)case 1:cout m;cout n;system(cls);if (flag = 0) a1 = new Matrix (m, n);a1-print();else a2 = new Matrix (m, n);a2-print();flag+;cout 创建成功 endl;break;case 2:cout n;system(cls);if (flag = 0) a1 = new Matrix (n);a1-print();else a2 = new Matrix (n);a2-print();flag+;cout 创建成功 endl;break;case 3:cout 输入矩阵行数 m;cout 输入矩阵列数 n;double *arr = new d

温馨提示

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

评论

0/150

提交评论