《[计算机软件及应用]算法设计与分析实验报告.doc》由会员分享,可在线阅读,更多相关《[计算机软件及应用]算法设计与分析实验报告.doc(49页珍藏版)》请在三一办公上搜索。
1、实验一 分治与递归(4学时)基本题一:基本递归算法一、实验目的与要求1、 熟悉C/C+语言的集成开发环境;2、 通过本实验加深对递归过程的理解二、实验内容:掌握递归算法的概念和基本思想,分析并掌握“整数划分”问题的递归算法。三、实验题任意输入一个整数,输出结果能够用递归方法实现整数的划分。四、实验步骤1 理解算法思想和问题要求;2 编程实现题目要求;3 上机输入和调试自己所编的程序;4 验证分析实验结果;5 整理出实验报告。五、结果截图:基本题二:棋盘覆盖问题一、实验目的与要求1、掌握棋盘覆盖问题的算法;2、初步掌握分治算法二、实验题: 盘覆盖问题:在一个2k2k 个方格组成的棋盘中,恰有一个
2、方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。三、实验提示void chessBoard(int tr, int tc, int dr, int dc, int size) if (size = 1) return; int t = tile+, / L型骨牌号 s = size/2; / 分割棋盘 / 覆盖左上角子棋盘 if (dr tr + s & dc tc + s) / 特殊方格在此棋盘中 chessBoard(tr, tc, dr, dc
3、, s); else / 此棋盘中无特殊方格 / 用 t 号L型骨牌覆盖右下角 boardtr + s - 1tc + s - 1 = t; / 覆盖其余方格 chessBoard(tr, tc, tr+s-1, tc+s-1, s); / 覆盖右上角子棋盘 if (dr = tc + s) / 特殊方格在此棋盘中 chessBoard(tr, tc+s, dr, dc, s); else / 此棋盘中无特殊方格 / 用 t 号L型骨牌覆盖左下角boardtr + s - 1tc + s = t; / 覆盖其余方格 chessBoard(tr, tc+s, tr+s-1, tc+s, s);
4、/ 覆盖左下角子棋盘 if (dr = tr + s & dc = tr + s & dc = tc + s) / 特殊方格在此棋盘中 chessBoard(tr+s, tc+s, dr, dc, s); else / 用 t 号L型骨牌覆盖左上角 boardtr + stc + s = t; / 覆盖其余方格 chessBoard(tr+s, tc+s, tr+s, tc+s, s); 四、结果截图提高题一:二分搜索一、实验目的与要求1、熟悉二分搜索算法;2、初步掌握分治算法;二、实验题1、设a0:n-1是一个已排好序的数组。请改写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大
5、元素的位置I和大于x的最小元素位置j。当搜索元素在数组中时,I和j相同,均为x在数组中的位置。结果截图:2、设有n个不同的整数排好序后存放于t0:n-1中,若存在一个下标I,0in,使得ti=i,设计一个有效的算法找到这个下标。要求算法在最坏的情况下的计算时间为O(logn)。结果截图:三、实验提示1、用I,j做参数,且采用传递引用或指针的形式带回值。bool BinarySearch(int a,int n,int x,int& i,int& j) int left=0; int right=n-1; while(leftamid) left=mid+1; else right=mid-1;
6、 i=right; j=left; return false;int SearchTag(int a,int n,int x) int left=0; int right=n-1; while(leftamid) right=mid-1; else left=mid+1; return -1;提高题二: 用分治法实现元素选择一、实验要求与目的1、了解分治法的基本思想,掌握递归程序编写方法;2、使用分治法编程,求解线形序列中第k小元素。二、实验内容1、 给定线形序列集中n个元素和一个整数k,1kn,输出这n个元素中第k小元素的值及其位置。2、 简述该算法的原理、步骤。对该算法与直接排序查找进行比
7、较。3、 编写并调试程序。测试要求:元素个数不少于100;分三种情况:k=1、k=n和k=中位数。#includeusing namespace std;/递归实现的函数int q(int n,int m)if(m1|n1)return 0;if(n=1|m=1)/int i=1;/coutn=1;/for(;in;i+)/cout+1;/coutendl;return 1;if(nm)return q(n,n);/最大的加数不可能大于nif(n=m)/coutn=nendl;return q(n,m-1)+1;/多一种被分解数的本身这种情况return q(n,m-1)+q(n-m,m);/
8、coutn=int main()int m;coutm;cout划分的个数为q(m,m)endl;return 0;/*该程序中为了输入输出的格式方便控制,在输出时采用了c语言的printf函数进行输出*/#includeusing namespace std;int Board130130;/Board为棋盘数组,k小于等于7int tile=1;/定义骨牌号void ChessBoard(int tr,int tc,int dr,int dc,int size)/将四为2k(size)的棋盘覆盖/tr,tc为棋盘的左上角方格所在的坐标,dr,dc为特殊方格所在的位置坐标 if (size
9、= 1) return; int t = tile+, / L型骨牌号 s = size/2; / 分割棋盘 / 覆盖左上角子棋盘 if (dr tr + s & dc tc + s) / 特殊方格在此棋盘中 ChessBoard(tr, tc, dr, dc, s); else / 此棋盘中无特殊方格 / 用 t 号L型骨牌覆盖右下角 Boardtr + s - 1tc + s - 1 = t; / 覆盖其余方格 ChessBoard(tr, tc, tr+s-1, tc+s-1, s); / 覆盖右上角子棋盘 if (dr = tc + s) / 特殊方格在此棋盘中 ChessBoard(
10、tr, tc+s, dr, dc, s); else / 此棋盘中无特殊方格 / 用 t 号L型骨牌覆盖左下角Boardtr + s - 1tc + s = t; / 覆盖其余方格 ChessBoard(tr, tc+s, tr+s-1, tc+s, s); / 覆盖左下角子棋盘 if (dr = tr + s & dc = tr + s & dc = tc + s) / 特殊方格在此棋盘中 ChessBoard(tr+s, tc+s, dr, dc, s); else / 用 t 号L型骨牌覆盖左上角 Boardtr + stc + s = t; / 覆盖其余方格 ChessBoard(tr
11、+s, tc+s, tr+s, tc+s, s); int main()int size=0,dr=0,dc=0;coutsize;cout请输入特殊方格所在的位置坐标(第一个方格的坐标为0):endl;coutdc;coutdr;Boarddrdc=-1;cout以下为棋盘的初始状态,0表示没有覆盖,-1表示特殊方格所在的位置:endl;int i=0,j=0;for(i=0;isize;i+)for(j=0;jsize;j+)printf(%3d,Boardij);coutendl;ChessBoard(0,0,dr,dc,size);cout以下为棋盘的覆盖后的状态,0表示没有覆盖,-1
12、表示特殊方格所在的位置,正整数表示骨牌号:endl;for(i=0;isize;i+)for(j=0;jsize;j+)printf(%3d,Boardij);coutendl;return 0;#includeusing namespace std; void BubbleSort(int* pData,int Count)/冒泡排序的函数,pData中从0位置处存了Count个数, 该函数将数组中元素排为升序 int iTemp; for(int i=1;i=i;j-) if(pDatajpDataj-1) iTemp = pDataj-1; pDataj-1 = pDataj; pDat
13、aj = iTemp; bool BinarySearch(int a,int n,int x,int& i,int& j)/数组a大小为n,数组中存放了已经排好序(升序)的数列 int left=0; int right=n-1;int mid=0; while(leftamid) left=mid+1; else right=mid-1; i=right; j=left; return false; /*int SearchTag(int a,int n,int x) int left=0; int right=n-1; while(leftamid) right=mid-1; else
14、left=mid+1; return -1;*/int main()int a100;coutnum;cout请输入数组中的数:endl;for(int i=0;iai;/下面将数组a排成升序BubbleSort(a,num);cout下面输出排序后的数组:endl;for(i=0;inum;i+)printf(%4d,ai);coutendl;coutx;int j=0;if(BinarySearch(a,num,x,i,j)cout找到了,位置为iendl;elsecout没找到,小于该数的最大元素位置为i大于该数的最小元素的位置为j(第一个元素的位置为0)endl;return 0;#i
15、ncludeusing namespace std; /*根据题目中的隐含要求,现在将问题进行简化,假设数组中存放的数全部为整数*/void BubbleSort(int* pData,int Count)/冒泡排序的函数,pData中从0位置处存了Count个数, 该函数将数组中元素排为升序 int iTemp; for(int i=1;i=i;j-) if(pDatajpDataj-1) iTemp = pDataj-1; pDataj-1 = pDataj; pDataj = iTemp; bool BinaryFind_iei(int a,int n,int& i)/数组a大小为n,数
16、组中存放了已经排好序(升序)的数列 int left=0; int right=n-1;int mid=0; while(leftamid)left=mid;elseright=mid; return false; /*int SearchTag(int a,int n,int x) int left=0; int right=n-1; while(leftamid) right=mid-1; else left=mid+1; return -1;*/int main()int a100;coutnum;cout请输入数组中的数:endl;for(int i=0;iai;/下面将数组a排成升序
17、BubbleSort(a,num);cout下面输出排序后的数组:endl;for(int i=0;inum;i+)printf(%4d,ai);coutendl;int j=0;if(BinaryFind_iei(a,num,j)cout找到了,位置为jendl;elsecout不存在符合第i个位置等于i的元素。endl;return 0;实验二 动态规划算法(4学时)基本题一:最长公共子序列问题一、实验目的与要求1、熟悉最长公共子序列问题的算法;2、初步掌握动态规划算法;二、实验题 若给定序列X=x1,x2,xm,则另一序列Z=z1,z2,zk,是X的子序列是指存在一个严格递增下标序列i1
18、,i2,ik使得对于所有j=1,2,k有:zj=xij。例如,序列Z=B,C,D,B是序列X=A,B,C,B,D,A,B的子序列,相应的递增下标序列为2,3,5,7。给定2个序列X和Y,当另一序列Z既是X的子序列又是Y的子序列时,称Z是序列X和Y的公共子序列。给定2个序列X=x1,x2,xm和Y=y1,y2,yn,找出X和Y的最长公共子序列。 三、实验提示include stdlib.h#include string.hvoid LCSLength(char *x ,char *y,int m,int n, int *c, int *b) int i ,j; for (i = 1; i = m
19、; i+) ci0 = 0; for (i = 1; i = n; i+) c0i = 0; for (i = 1; i = m; i+) for (j = 1; j =cij-1) cij=ci-1j; bij=2; else cij=cij-1; bij=3; void LCS(int i ,int j, char *x ,int *b) if (i =0 | j=0) return; if (bij= 1) LCS(i-1,j-1,x,b); printf(%c,xi); else if (bij= 2) LCS(i-1,j,x,b); else LCS(i,j-1,x,b);四、实验结
20、果截图基本题二:最大字段和问题一、实验目的与要求1、熟悉最长最大字段和问题的算法;2、进一步掌握动态规划算法;二、实验题 若给定n个整数组成的序列a1,a2,a3,an,求该序列形如aiai1an的最大值。三、实验提示int MaxSum(int n,int *a,int &besti,int &bestj) intsum=0; for(int i=1;i=n;i+) for(int j=i;j=n;j+) int thissum=0; for(int K=i;ksum) sum=thissum; besti=i; bestj=j; return sum;int MaxSum(int n,in
21、t *a,int &besti,int &bestj) intsum=0; for(int i=1;i=n;i+) int thissum=0; for(intj=i;jsum) sum=thissum; besti=i; bestj=j; return sum; 四、实验结果截图提高题一: 用动态规划法求解0/1背包问题一、实验要求与目的1、 掌握动态规划算法求解问题的一般特征和步骤。2、 使用动态规划法编程,求解0/1背包问题。二、实验内容1、 问题描述:给定n种物品和一个背包,物品i的重量是Wi,其价值为Vi,问如何选择装入背包的物品,使得装入背包的物品的总价值最大?2、 算法描述。3、
22、 程序实现;给出实例测试结果。二、实验结果截图#includeusing namespace std;/构造最大子序列,完成之后,最大子序列信息存放在数组c中,构造方法存在b中void LCSLength(char *x ,char *y,int m,int n, int c100, int b100) int i ,j; for (i = 0; i = m; i+) ci0 = 0; for (i = 0; i = n; i+) c0i = 0; for (i = 1; i = m; i+) for (j = 1; j =cij-1) cij=ci-1j; bij=2; else cij=c
23、ij-1; bij=3; /下面构造最长子序列void LCS(int i ,int j, char *x ,int b100) if (i =0 | j=0) return; if (bij= 1) LCS(i-1,j-1,x,b); printf(%c,xi); else if (bij= 2) LCS(i-1,j,x,b); else LCS(i,j-1,x,b);int main()int m,n;coutm;coutn;char *b1=new charm+1;char *b2=new charn+1;if(b1=NULL|b2=NULL)coutmeiyouchenggongfen
24、peiendl;cout输入第一个序列:endl;b10=b20=0;int i=0;for(i=1;i=m;i+)cout 请输入第一个序列b1的第ib1i;cout输入第二个序列:endl;for(i=1;i=n;i+)cout 请输入第二个序列b2的第ib2i;int c100100,b100100;LCSLength(b1,b2,m,n,c,b);/void LCSLength(char *x ,char *y,int m,int n, int *c, int *b)cout最长公共子序列的长度为cmnendl;LCS(m,n,b1,b);/void LCS(int i ,int j,
25、 char *x ,int *b)delete b1;delete b2;coutendl;return 0;#includeusing namespace std;int MaxSum(int n,int *a)int sum=0,b=0;for(int i=1;i0)b=b+ai;elseb=ai;if(bsum)sum=b;return sum;int main()coutl;int *a=new intl+1;if(l=NULL)coutchucuole,hheh.endl;return 0;a0=0;for(int i=1;i=l;i+)cout请输入整数序列的第iai;cout最大
26、字段和为MaxSum(l,a)endl;delete a;return 0;#includeusing namespace std;int MaxSum(int n,int *a)int sum=0,b=0;for(int i=1;i0)b=b+ai;elseb=ai;if(bsum)sum=b;return sum;int main()coutl;int *a=new intl+1;if(l=NULL)coutchucuole,hheh.endl;return 0;a0=0;for(int i=1;i=l;i+)cout请输入整数序列的第iai;cout最大字段和为MaxSum(l,a)en
27、dl;delete a;return 0;#includeusing namespace std;int min(int x,int y)return xy?y:x;int max(int x,int y)return xy?x:y;void Knapsack(int *v,int *w,int c,int n,int m100)int jMax=min(wn-1,c);for(int j=0;j=jMax;j+)mnj=0;for(int j=wn;j1;i-)jMax=min(wi-1,c);int j=0;for(j=0;j=jMax;j+)mij=mi+1j;for(j=wi;j=wi
28、)m1c=max(m1c,m2c-wi+v1);void traceback(int m100,int *w,int c,int n,int *x)for(int i=1;in;i+)if(mic=mi+1c)xi=0;elsexi=1;c=c-wi;xn=mnc?1:0;int main()coutc;coutn;int *v=new intn+1;int *w=new intn+1;int *x=new intn+1;if(x=NULL|w=NULL|v=NULL)coutmeiyou chenggong fenpei,heheendl;return 0;/Knapsack(int *v.int *w,int c,int m100)/viod traceback(int m100,int *w,int c,int n,int *x)cout请输入待放物体的价值和重量信息:endl;int i=0;for(i=1;i=n;i+)cout 第ivi;cout 第i个物体的重量: