ImageVerifierCode 换一换
格式:DOCX , 页数:25 ,大小:309.22KB ,
资源ID:9221533      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9221533.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(程序设计方法专题实验报告.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

程序设计方法专题实验报告.docx

1、程序设计方法专题实验报告程 序 设 计 方 法专题实验实验任务实验任务一:矩阵乘积问题描述:已知矩阵A,B, 当A的列数和B的行数相同时,则A与B可以相乘,其乘积为一个m*p的矩阵D:其中dij= (i=1,2,m;j=1,2,p)。简记为D=A*B,其中:已知矩阵A,B,C中大多数元素为0,这种矩阵称为稀疏矩阵,可采用三元组表示矩阵的的i行第j列的值为a,其他未列出的元素的值均为0,在计算机中,可以用行优先法给出稀疏矩阵中的非0元素的三元组,首先是第1行按列给出,然后是第2行按列给出例如矩阵: 那么该矩阵的三元组表示为:1 1 12 3 22 4 -13 2 13 3 23 4 3实验要求:

2、编程完成计算D=A*B*C第i行第j列的值。输入文件说明:第一行:x,y两个正整数,分别表示输出结果在矩阵D中的行和列。第二行:m,n,o,p,表示A为矩阵mn矩阵,B为no矩阵,C为op矩阵。第三行及以后各行是:i,j,a,表示矩阵的三元组表示法中的一个元素的值,每个矩阵之间有一个空行。矩阵的表示顺序为A,B,C。注:1m,n,o,p6000,即三元组的总个数不大于6000.数据之间用空格分开。输出文件:一行,为D=A*B*C的第x行y列元素的值。算法设计及主要程序:问题分析:本题的主要考虑两个方面,一是稀疏矩阵的压缩储存,二是两个稀疏矩阵之间的乘法。其中最重要的一步又是矩阵的三元组乘法。任

3、务一流程图(1).根据矩阵相乘的定义有:, 在经典算法中,不论,的值是否为0,都要进行一次乘法,而实际上,这两者有一个值值为0时,其积也为0。因此,在对稀疏矩阵进行相乘运算时,应该免去这种无效操作,为求Q的值,只需在M.data中和N.data中找到对应元素(即M.data中的j与N.data中的i相等的元素)相乘即可。(2).这样相乘的基本操作是:对于M中的每个元素M.datap(p=1,2,3,M.da_num),找到N中所有满足M.datap.j= N.datap.i的元素N.dataq,求得其乘积。由于矩阵Q中每个元素的值是个累计和,这个乘积M.datap.vN.datap.v只是Qi

4、j的一部分。为了便于操作,应当对每个元素设计一个累计和变量,其初值为0,然后扫描数组M,求得相应元素的乘积并累加到适当的求和累计和的变量上。(3).两个稀疏矩阵相乘的乘积不一定为零矩阵。而两个即使矩阵的分量不为0,而乘积也可能是0。因此乘积矩阵Q中的元素是否为非零元,只有在求得其累加和后才能得知。由于Q中元素的行号和M中的行号一致,由此可对Q进行逐行处理,先求得累计求和的中间结果(Q的一行),然后再压缩到Q.data中去。在解决了稀疏矩阵三元组相乘后,其储存结构也就迎刃而解了。只需够造一个三元组类记录三元组的属性(行号,列号,值),在构造矩阵类的时候加入属性举证行数,列数,三元组非零元总数,行

5、优先标记数组就可。根据以上分析,程序设计流程图如上面所示:其中最重要的矩阵的三元组乘法程序如下:/-两稀疏矩阵相乘的主要算法,定义为友元函数-/Matrix Mult_Matrix(Matrix& m,Matrix& n) Matrix Q(m.row,n.col); int *ctemp=new intn.col; int tp,t_row,tr,t_col; if(m.col!=n.row) cout两矩阵不能相乘!i=i; this-j=j; this-e=e; void set_data(int i,int j,int e) this-i=i; this-j=j; this-e=e;

6、;/-/定义矩阵类-/class Matrixpublic: vector da; int ropsMAXSIZE; int row,col,da_num; Matrix() row=0; col=0; da_num=0; Matrix(int row,int col,int da_num=0) this-row=row; this-col=col; this-da_num=da_num; for(int i=0;i!=da_num;+i) ropsi=-1; void put_data(data d) if(!da.size() put_rops(d.i,da.size(); if(da.s

7、ize()&d.i!=dada.size()-1.i) put_rops(d.i,da.size(); da.push_back(d); void put_rops(int m,int n) ropsm=n; int get_number(int m,int n) for(int i=0;i!=da_num;+i) if(dai.i=m&dai.j=n) return dai.e; return 0; friend Matrix Mult_Matrix(Matrix& m,Matrix& n);/-/运行结果:本程序在Linux GCC和Windos SP2 VC+2008下均调试通过。其运行

8、结果如下:程序结果分析: 分析算法的时间复杂度有如下结果:累加器ctemp初始化的效率为O(A.da_num*B.da_num),求两矩阵相乘结果中的所有非零元的时间复杂度为O(M.col*N.col/N.row),进行压缩的时间复杂度为O(M.row*N.col),总的时间复杂度为O(M.row*N.col+M.col*N.col/N.row)。实验任务二:单词统计问题描述:统计输入文件中出现的不同的单词个数以及每个单词出现的频率,并起将这些单词按照词典的顺序排列好输出到文件中。实验要求:输入:以文件的形式记录程序中所需要的数据。输出:结果应该存放在一个文件中,该文件的第一行是不同的单词个数

9、,从第二行开始则为每个单词和其相应的频率,单词与频率之间用空格符分割,单词需按字典顺序排列。算法设计与主要程序段:问题分析:本题的主要是单词的有序统计,主要难点在于如何设计高效的统计函数,达到广泛的统计要求(一般可统计数百万单词),首先是读入文件时的单词分割,然后是两个单词的比较(本题而言,可以重载“”和“”操作符),单词分割和两个单词的比较都比较简单,时间代价是线性的0(1),故不需要优化。只要是单词的统计上,如何去寻找好的数据结构和高效的算法。首先可以想到数组,数组的优点是其有序性,故重载“”和“”操作符时可以利用二分查找法插入位置,时间代价为0(log(n),但是在新的单词插入后,整个数

10、组的序列会改变,这种元素移位操作却非常耗时,代价为O(n2),再加上数组对统计单词数具有容量限制(数组的大小必须实现分配),就算用优化后的向量可以满足动态分配内存,但总的说来时间时间代价昂贵,不能采用。再次是链表,链表优点可以动态分配内存,对单词的统计量没有限制,缺点是没有好的方法来实现重载“”和“”操作符,这个代价是0(n2)。当然优化后的List在排序时可以小一点,但时间效代价仍然非常昂贵,也不能采用。考虑到前面两种数据结构各自的优缺点,可以直到数据结构中的二叉排序树(AVL)可以很好的解决动态储存空间的分配和插入查找,其时间代价为O(log(n),已经非常廉价,但AVL在实现重载“”和“

11、”操作符只能单向二分,为此可以对节点进行红黑标记,实现双向二分查找。任务二流程图查找与插入问题解决后,接下来就是单词与其个数之间的关系问题。利用红黑数时,不妨可采用每个节点5个域,分别标记前驱,后继,红黑标记,键(单词),码(单词个数)。这样的优点是可以将单词与其个数之间形成二元关系,即二元键值对。通过“=a&z=si)|(si=A&Z=si)&i!=s.size() +i; j=i; while(sj=a&z=sj)|(sj=A&Z=sj)|(sj=39) +j; if(i=s.size() return false; for(;i!=j&i!=s.size();+i) if(sia) si

12、=si+a-A; temp.push_back(si); s=temp; return true;/-/单词计数数据结构map的选择:/-/ map counters; int sum=0; string s; while(ins) if(changeWords(s) counterss+; sum+; /-/运行结果:本程序在Linux GCC和Windos SP2 VC+2008下均调试通过。其运行结果如下:程序结果分析:进行单词统计的时候,只统计ASCII编码的单词,对于其他编码,如UNICLDE,GB2312,GBK,BIG5等编码的全角字母(占两个字节),全部滤过不做统计,对汉字及其

13、他双字节的文字一律滤过,不做统计。算法设计主要是利用map中红黑树,实现键值对,一个单词(键)对应一个值(值),形成映射.在查找和插入时主要是红黑数的双向二分查找插入,效率为O(log(size_of_map),对于本程序的运用(统计量大约在10MB,1000000个单词以下来说,效率是可以接受的)。如果需要进行更大的统计,则可以用hash表来实现编码。查找和插入时间效率为O(1)。但是编码和处理地址冲突的指令较多,所以在统计少量的单词时,反而没有map快,同时由于统计对单词是有序要求,hash技术对于保持有序上很难做到,故另外还需要设计排序方案,但排序本身也是一个很耗时的事情,因而本题目的最

14、佳选择还是map。实验任务三:指针式时钟实验要求:可视化的显一个指针式模拟时钟;可为程序设计一个美观大方的图标;通过菜单可以调整时间,定制指针式时钟的显示风格,比如指针、表盘的颜色、外形等,可以按照个人的兴趣进行其他的属性的扩展。主要设计思路和所涉及的类:本题是一个可视化编程问题,目前可视化编程工具比较多,我采用的是比较流行的VC。对于题目要求的可视化,可以建一个SDI(单文档视图结构)程序,设计主要分为可视化和控件标准两部分。前一部分主要在Cview类中完成,后一部分主要在Cframe类中完成。其中可视化画图主要在OnDraw函数中添加代码实现。设计时首先是读取时间,现在读取时间的方式主要有

15、从操作系统和网络远程读取,由于寝室上网不方便,我采用的是从操作系统中读取时间,然后由时间变量用三角函数转换得到各个指针的首末坐标,进而画出表盘,再添加计时器,每个一秒重新读取一次新时间,并更新表盘画面,这样就可以使闹钟动起来。各个控件的属性与响应函数可以自己在Cframe类中添加代码完成。按照以上的设计规划,可以将整个任务分为以下三块:1读取时间,以及记录闹钟的时间等,设定定时器。2画出表盘时钟,实现美观大方的可视化。3附加功能,如闹钟,日列,备忘录等控件设计。对于第一块,先定义几个全局型变量extern bool ifon; /闹钟标记extern bool ifsound; /闹钟声音标记

16、extern int h,m,s; /分别记录闹钟的时分秒再设计计时器,使之每一秒钟向系统读一次时间。代码如下:int CAlarmClockView:OnCreate(LPCREATESTRUCT lpCreateStruct) if (CFormView:OnCreate(lpCreateStruct) = -1) return -1; / TODO: Add your specialized creation code here /设置时间步长为1s. SetTimer(1,1000,NULL); return 0;接下来将重操作系统读取的UNIX时间节转化为时分秒数字时钟。代码为:CT

17、ime Now=CTime:GetCurrentTime(); /读取操作系统的时间。m_tDate=Now;UpdateData(false);m_dDate.SetToday(&Now); /将UNIX时间节转化数字形式 CString s1,stime,ntime;stime.Format(%d:%02d:%02d,h,m,s); /将闹钟时间格式化/将UNIX时间节转化为时分秒数字时钟,并格式化ntime.Format(%d:%02d:%02d,Now.GetHour(),Now.GetMinute(),Now.GetSecond();第二块,有了以上读出的系统时间后,就可以根据时间变

18、量来画出此时刻的半盘,代码如下:/界面美观性的设计if (Now.GetHour()=11) s1=早上好,欢迎您使用Rolex情侣珍藏版AlarmClock!; else if (Now.GetHour()=13) s1=中午好,欢迎您使用Rolex情侣珍藏版AlarmClock!; else if (Now.GetHour()SetTextColor(RGB(0,0,255); pDC-TextOut(90,15,s1); /为闹钟同时也设计界面 if(!ifon) m_Static1.ShowWindow(false); pDC-SetTextColor(RGB(255,0,0); pD

19、C-TextOut(60,245,闹铃功能未启动); else m_Static1.ShowWindow(true); pDC-SetTextColor(RGB(255,0,0); pDC-TextOut(60,245,闹铃已启动,时间为+stime); pDC-SetTextColor(RGB(0,0,0); pDC-TextOut(300,230,现在时刻:); pDC-Rectangle(365,255,465,270); pDC-SetTextColor(RGB(0,255,255); pDC-TextOut(300,255,ntime); CBrush br,br1; br.Crea

20、teSolidBrush(RGB(0,255,0); pDC-SelectStockObject(NULL_PEN); pDC-SelectObject(&br); int l; l=int(double)Now.GetHour()+(double)Now.GetMinute()/60.0+(double)Now.GetSecond()/3600.0)/24.0*100); pDC-Rectangle(366,256,366+l,270); br1.CreateSolidBrush(RGB(255,255,255); pDC-SelectObject(&br1); /画表盘 int nCent

21、erX = 385; int nCenterY = 135; CString strDigits; int i,x,y; CSize size; CPen Pen(PS_SOLID,5,RGB(0,128,255); CPen *pOldPen=pDC-SelectObject(&Pen); pDC-Ellipse(300,50,470,220); double Radians; pDC-SetTextColor(RGB(0,0,0); for(i=1;iGetTextExtent(strDigits,strDigits.GetLength(); Radians = (double) i *

22、6.28 / 12.0; x=nCenterX-(size.cx/2)+(int)(double)72*sin(Radians); y=nCenterY-(size.cy/2)-(int)(double)72*cos(Radians); pDC-TextOut( x, y, strDigits ); Radians=(double)Now.GetHour()+(double)Now.GetMinute()/60.0+(double)Now.GetSecond()/3600.0; /画表盘主要利用三角函数进行坐标变化。 Radians*=2*3.14159/12.0; CPen HourPen(

23、PS_SOLID,5,RGB(233,233,15); pDC-SelectObject(&HourPen); pDC-MoveTo(nCenterX,nCenterY); pDC-LineTo(nCenterX+(int)(double)(25)*sin(Radians),nCenterY-(int)(double)(25)*cos(Radians); /画时间指针 Radians=(double)Now.GetMinute()+(double)Now.GetSecond()/60.0; Radians*=2*3.14159/60.0; CPen MinutePen(PS_SOLID,3,RGB(0,0,255); pDC-SelectObject(&MinutePen); pDC-MoveTo(nCenterX,nCenterY); pDC-LineTo(nCenterX+(int)(double)(40)*sin(Radians),nCenterY-(int)(do

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1