算法设计与分析实验报告3
- 格式:pdf
- 大小:363.60 KB
- 文档页数:13
实验一递归与分治策略一、实验目的1.加深学生对分治法算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。
二、实验内容1、①设a[0:n-1]是已排好序的数组。
请写二分搜索算法,使得当搜索元素x不在数组中时,返回小于x的最大元素位置i和大于x的最小元素位置j。
当搜索元素在数组中时,i和j相同,均为x在数组中的位置。
②写出三分搜索法的程序。
三、实验要求(1)用分治法求解上面两个问题;(2)再选择自己熟悉的其它方法求解本问题;(3)上机实现所设计的所有算法;四、实验过程设计(算法设计过程)1、已知a[0:n-1]是一个已排好序的数组,可以采用折半查找(二分查找)算法。
如果搜索元素在数组中,则直接返回下表即可;否则比较搜索元素x与通过二分查找所得最终元素的大小,注意边界条件,从而计算出小于x的最大元素的位置i和大于x的最小元素位置j。
2、将n个元素分成大致相同的三部分,取在数组a的左三分之一部分中继续搜索x。
如果x>a[2(n-1)/3],则只需在数组a的右三分之一部分中继续搜索x。
上述两种情况不成立时,则在数组中间的三分之一部分中继续搜索x。
五、实验结果分析二分搜索法:三分搜索法:时间复杂性:二分搜索每次把搜索区域砍掉一半,很明显时间复杂度为O(log n)。
(n代表集合中元素的个数)三分搜索法:O(3log3n)空间复杂度:O(1)。
六、实验体会本次试验解决了二分查找和三分查找的问题,加深了对分治法的理解,收获很大,同时我也理解到学习算法是一个渐进的过程,算法可能一开始不是很好理解,但是只要多看几遍,只看是不够的还要动手分析一下,这样才能学好算法。
七、附录:(源代码)二分搜索法:#include<iostream.h>#include<stdio.h>int binarySearch(int a[],int x,int n){int left=0;int right=n-1;int i,j;while(left<=right){int middle=(left+right)/2;if(x==a[middle]){i=j=middle;return 1;}if(x>a[middle])left=middle+1;else right=middle-1;}i=right;j=left;return 0;}int main(){ int a[10]={0,1,2,3,4,5,6,7,8,9};int n=10;int x=9;if(binarySearch(a,x,n))cout<<"找到"<<endl;elsecout<<"找不到"<<endl;return 0;}实验二动态规划——求解最优问题一、实验目的1.加深学生对动态规划算法设计方法的基本思想、基本步骤、基本方法的理解与掌握;2.提高学生利用课堂所学知识解决实际问题的能力;3.提高学生综合应用所学知识解决实际问题的能力。
算法设计与分析实验报告一实验名称统计数字问题评分实验日期2014 年11 月15 日指导教师姓名专业班级学号一.实验要求1、掌握算法的计算复杂性概念。
2、掌握算法渐近复杂性的数学表述。
3、掌握用C++语言描述算法的方法。
4.实现具体的编程与上机实验,验证算法的时间复杂性函数。
二.实验内容统计数字问题1、问题描述一本书的页码从自然数1 开始顺序编码直到自然数n。
书的页码按照通常的习惯编排,每个页码都不含多余的前导数字0。
例如,第6 页用数字6 表示,而不是06 或006 等。
数字计数问题要求对给定书的总页码n,计算出书的全部页码中分别用到多少次数字0,1,2, (9)2、编程任务给定表示书的总页码的10 进制整数n (1≤n≤109) 。
编程计算书的全部页码中分别用到多少次数字0,1,2, (9)三.程序算法将页码数除以10,得到一个整数商和余数,商就代表页码数减余数外有多少个1—9作为个位数,余数代表有1—余数本身这么多个数作为剩余的个位数,此外,商还代表1—商本身这些数出现了10次,余数还代表剩余的没有计算的商的大小的数的个数。
把这些结果统计起来即可。
四.程序代码#include<iostream.h>int s[10]; //记录0~9出现的次数int a[10]; //a[i]记录n位数的规律void sum(int n,int l,int m){ if(m==1){int zero=1;for(int i=0;i<=l;i++) //去除前缀0{ s[0]-=zero;zero*=10;} }if(n<10){for(int i=0;i<=n;i++){ s[i]+=1; }return;}//位数为1位时,出现次数加1//位数大于1时的出现次数for(int t=1;t<=l;t++)//计算规律f(n)=n*10^(n-1){m=1;int i;for(i=1;i<t;i++)m=m*10;a[t]=t*m;}int zero=1;for(int i=0;i<l;i++){ zero*= 10;} //求出输入数为10的n次方int yushu=n%zero; //求出最高位以后的数int zuigao=n/zero; //求出最高位zuigaofor(i=0;i<zuigao;i++){ s[i]+=zero;} //求出0~zuigao-1位的数的出现次数for(i=0;i<10;i++){ s[i]+=zuigao*a[l];} //求出与余数位数相同的0~zuigao-1位中0~9出现的次数//如果余数是0,则程序可结束,不为0则补上所缺的0数,和最高位对应所缺的数if(yushu==0) //补上所缺的0数,并且最高位加1{ s[zuigao]++;s[0]+=l; }else{ i=0;while((zero/=10)>yushu){ i++; }s[0]+=i*(yushu+1);//补回因作模操作丢失的0s[zuigao]+=(yushu+1);//补回最高位丢失的数目sum(yushu,l-i-1,m+1);//处理余位数}}void main(){ int i,m,n,N,l;cout<<"输入数字要查询的数字:";cin>>N;cout<<'\n';n = N;for(i=0;n>=10;i++){ n/=10; } //求出N的位数n-1l=i;sum(N,l,1);for(i=0; i<10;i++){ cout<< "数字"<<i<<"出现了:"<<s[i]<<"次"<<'\n'; }}五.程序调试中的问题调试过程,页码出现报错。
实验一全排列、快速排序【实验目的】1.掌握全排列的递归算法。
2.了解快速排序的分治算法思想。
【实验原理】一、全排列全排列的生成算法就是对于给定的字符集, 用有效的方法将所有可能的全排列无重复无遗漏地枚举出来。
任何n个字符集的排列都可以与1~n的n个数字的排列一一对应, 因此在此就以n个数字的排列为例说明排列的生成法。
n个字符的全体排列之间存在一个确定的线性顺序关系。
所有的排列中除最后一个排列外, 都有一个后继;除第一个排列外, 都有一个前驱。
每个排列的后继都可以从它的前驱经过最少的变化而得到, 全排列的生成算法就是从第一个排列开始逐个生成所有的排列的方法。
二、快速排序快速排序(Quicksort)是对冒泡排序的一种改进。
它的基本思想是: 通过一趟排序将要排序的数据分割成独立的两部分, 其中一部分的所有数据都比另外一部分的所有数据都要小, 然后再按此方法对这两部分数据分别进行快速排序, 整个排序过程可以递归进行, 以此达到整个数据变成有序序列。
【实验内容】1.全排列递归算法的实现。
2.快速排序分治算法的实现。
【实验结果】1.全排列:快速排序:实验二最长公共子序列、活动安排问题【实验目的】了解动态规划算法设计思想, 运用动态规划算法实现最长公共子序列问题。
了解贪心算法思想, 运用贪心算法设计思想实现活动安排问题。
【实验原理】一、动态规划法解最长公共子序列设序列X=<x1, x2, …, xm>和Y=<y1, y2, …, yn>的一个最长公共子序列Z=<z1, z2, …, zk>, 则:..i.若xm=yn, 则zk=xm=yn且Zk-1是Xm-1和Yn-1的最长公共子序列...ii.若xm≠yn且zk≠x., 则Z是Xm-1和Y的最长公共子序列...iii.若xm≠yn且zk≠y.,则Z是X和Yn-1的最长公共子序列.其中Xm-1=<x1, x2, …, xm-1>, Yn-1=<y1, y2, …, yn-1>, Zk-1=<z1, z2, …, zk-1>。
实验一排序算法设计一、实验内容冒泡排序二、实验问题分析该问题主要涉及到了指针和循环和相互比较的方法,是综合知识的应用。
三、数学模型根据题目要求,依次对每个数据进行比较,直至得出最后结果。
如果a>b则交换位置,如果a<b则不交换。
四、程序流程图五、源代码#include <stdio.h>void sort(int a[]){int temp;for(int i=0;i<9;i++){for(int j=0;j<10-i-1;j++){if(a[j]>a[j+1]){temp=a[j];a[j]=a[j+1];a[j+1]=temp;}}}printf("排序后的数据\n"); for(i=0;i<10;i++){if(i==5){printf("\n");}printf("%d ",a[i]);}printf("\n");}void main(){int a[10];for(int i=0;i<10;i++){scanf("%d",&a[i]);}printf("排序前的数据\n"); for(i=0;i<10;i++){if(i==5){printf("\n");}printf("%d ",a[i]);}printf("\n");sort(a);}六、测试结果实验二递归算法设计一、实验内容1.判断S字符是否为“回文”的递归函数,并编写程序测试。
二、实验问题分析递归是一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法。
递归算法设计,就是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题,在逐步求解小问题后,再返回(回溯)得到大问题的解。
算法设计与分析实验报告姓名:班级:计算机科学与技术102班学号:1090教师:设计时间:2012.04.23编程工具:C-Free 5.0【实验一】:使用递归方法输出杨辉三角杨辉三角.cpp//使用递归方法输出杨辉三角,每个数字占用4个空格位#include <stdlib.h>#include <stdio.h>int calcit(int x, int y){if (x==y||y==0)return 1;elsereturn calcit(x-1,y-1)+calcit(x-1,y);}int main(){int i, j,k,n;printf("请输入行数(最好<=13):");scanf("%d",&n);for (i = 0; i<n; i++){for(k=(n-i)*2;k>0;k--)printf(" ");for (j=0;j<=i;j++)printf("%4d",calcit(i, j));printf("\n");}return 0;}【实验二】:快速排序(一)快速排序.cpp#include<stdio.h>#include<stdlib.h>#define SIZE 100void quick_sort(int data[],int x,int y);int pation(int data[],int x,int y);int main(){int i,n,data[SIZE];printf("请输入要排列的数目(<=100):");scanf("%d",&n);printf("请输入要排列的数列:\n");for(i=0;i<n;++i)scanf("%d",&data[i]);quick_sort(data,0,n-1);printf("排列后的数列为:\n");for(i=0;i<n;++i)printf( "%d ",data[i]);printf("\n");return 0;}void quick_sort(int data[],int x,int y){if(x>=y) return;int q=pation(data,x,y);quick_sort(data,x,q-1);quick_sort(data,q+1,y);}int pation(int data[],int x,int y){int n=data[x],i=x+1,j=y,temp;while(1){while(data[i]<n) ++i;while(data[j]>n) --j;if(i>=j) break;temp=data[i]; data[i]=data[j]; data[j]=temp;}data[x]=data[j];data[j]=n;return j;}(二)插入排序.cpp#include<stdio.h>#include<conio.h>#define X 100#define Y 100int main(){int a[X],r[Y];int *p;int i,j,n;printf("请输入要排列的数目(<=100):");scanf("%d",&n);printf("请输入要排列的数列:\n");for(i=0;i<n;i++){p=&a[i];scanf("%d",p);r[i+1]=a[i];}r[0]=1;for(i=2;i<=n;i++){r[0]=r[i];j=i-1;while(r[j]>r[0]){r[j+1]=r[j];j--;}r[j+1]=r[0];}printf("排列后的顺序是:\n");for(i=1;i<=n;i++){p=&r[i];printf("%d ",*p);}printf("\n");return 0;}【实验三】:趣味矩阵(一)次上三角的自动打印次上三角的自动打印.cpp#include "stdio.h"#include "stdlib.h"#define MAX 100void InterestMatrix(int n){int a[MAX][MAX];int k=1,m=0; // 计数器int i,j;//矩阵初始化for(i=0;i<n;i++){for(j=0;j<=i;j++)a[i][j]=k++;}//打印矩阵for(i=0;i<n;i++){m=i;for(j=0;j<n-i;j++)printf("%d ",a[m++][j]);printf("\n");}}int main(){int n;printf("输入矩阵的阶数n:");scanf("%d",&n);printf("\n");InterestMatrix(n);printf("\n");return 0;}(二)特殊趣味矩阵的打印趣味矩阵.cpp//使左对角线和右对角线上的元素为0,它们上方的元素为1,左边的元素为2,下方的元素为3,右边的元素为4#include<stdio.h>int main(){int i,j,a[100][100],n;printf("请输入矩阵的阶数:");scanf("%d",&n);for(i=1;i<=n;i++)for(j=1;j<=n;j++){if(i==j||i+j==n+1)a[i][j]=0;if(i<j&&i+j<n+1)a[i][j]=1;if(i>j&&i+j<n+1)a[i][j]=2;if(i>j&&i+j>n+1)a[i][j]=3;if(i<j&&i+j>n+1)a[i][j]=4;}for(i=1;i<=n;i++){printf("\n");for(j=1;j<=n;j++)printf("%d ",a[i][j]);}printf("\n");return 0;}。
第1篇一、实验背景与目的随着计算机技术的飞速发展,算法在计算机科学中扮演着至关重要的角色。
为了加深对算法设计与分析的理解,提高实际应用能力,本实验课程设计旨在通过实际操作,让学生掌握算法设计与分析的基本方法,学会运用所学知识解决实际问题。
二、实验内容与步骤本次实验共分为三个部分,分别为排序算法、贪心算法和动态规划算法的设计与实现。
1. 排序算法(1)实验目的:熟悉常见的排序算法,理解其原理,比较其优缺点,并实现至少三种排序算法。
(2)实验内容:- 实现冒泡排序、快速排序和归并排序三种算法。
- 对每种算法进行时间复杂度和空间复杂度的分析。
- 编写测试程序,对算法进行性能测试,比较不同算法的优劣。
(3)实验步骤:- 分析冒泡排序、快速排序和归并排序的原理。
- 编写三种排序算法的代码。
- 分析代码的时间复杂度和空间复杂度。
- 编写测试程序,生成随机测试数据,测试三种算法的性能。
- 比较三种算法的运行时间和内存占用。
2. 贪心算法(1)实验目的:理解贪心算法的基本思想,掌握贪心算法的解题步骤,并实现一个贪心算法问题。
(2)实验内容:- 实现一个贪心算法问题,如活动选择问题。
- 分析贪心算法的正确性,并证明其最优性。
(3)实验步骤:- 分析活动选择问题的贪心策略。
- 编写贪心算法的代码。
- 分析贪心算法的正确性,并证明其最优性。
- 编写测试程序,验证贪心算法的正确性。
3. 动态规划算法(1)实验目的:理解动态规划算法的基本思想,掌握动态规划算法的解题步骤,并实现一个动态规划算法问题。
(2)实验内容:- 实现一个动态规划算法问题,如背包问题。
- 分析动态规划算法的正确性,并证明其最优性。
(3)实验步骤:- 分析背包问题的动态规划策略。
- 编写动态规划算法的代码。
- 分析动态规划算法的正确性,并证明其最优性。
- 编写测试程序,验证动态规划算法的正确性。
三、实验结果与分析1. 排序算法实验结果:- 冒泡排序:时间复杂度O(n^2),空间复杂度O(1)。
算法设计与分析实验报告算法设计与分析实验报告引言:算法设计与分析是计算机科学中的重要课程,它旨在培养学生解决实际问题的能力。
本次实验旨在通过设计和分析不同类型的算法,加深对算法的理解,并探索其在实际应用中的效果。
一、实验背景算法是解决问题的步骤和方法的描述,是计算机程序的核心。
在本次实验中,我们将重点研究几种经典的算法,包括贪心算法、动态规划算法和分治算法。
通过对这些算法的设计和分析,我们可以更好地理解它们的原理和应用场景。
二、贪心算法贪心算法是一种基于局部最优选择的算法,它每一步都选择当前状态下的最优解,最终得到全局最优解。
在实验中,我们以背包问题为例,通过贪心算法求解背包能够装下的最大价值物品。
我们首先将物品按照单位重量的价值从大到小排序,然后依次将能够装入背包的物品放入,直到背包无法再装下物品为止。
三、动态规划算法动态规划算法是一种通过将问题分解为子问题,并记录子问题的解来求解整体问题的算法。
在实验中,我们以斐波那契数列为例,通过动态规划算法计算斐波那契数列的第n项。
我们定义一个数组来保存已经计算过的斐波那契数列的值,然后通过递推公式将前两项的值相加得到后一项的值,最终得到第n项的值。
四、分治算法分治算法是一种将问题分解为更小的子问题,并通过递归求解子问题的算法。
在实验中,我们以归并排序为例,通过分治算法对一个无序数组进行排序。
我们首先将数组分成两个子数组,然后对子数组进行递归排序,最后将两个有序的子数组合并成一个有序的数组。
五、实验结果与分析通过对以上三种算法的设计和分析,我们得到了以下实验结果。
在贪心算法中,我们发现该算法能够在有限的时间内得到一个近似最优解,但并不能保证一定得到全局最优解。
在动态规划算法中,我们发现该算法能够通过记忆化搜索的方式得到准确的结果,但在问题规模较大时,其时间复杂度较高。
在分治算法中,我们发现该算法能够将问题分解为更小的子问题,并通过递归求解子问题,最终得到整体问题的解。
实验一找最大和最小元素与归并分类算法实现(用分治法)一、实验目的1.掌握能用分治法求解的问题应满足的条件;2.加深对分治法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
二、实验内容1、找最大和最小元素输入n 个数,找出最大和最小数的问题。
2、归并分类将一个含有n个元素的集合,按非降的次序分类(排序)。
三、实验要求(1)用分治法求解问题(2)上机实现所设计的算法;四、实验过程设计(算法设计过程)1、找最大和最小元素采用分治法,将数组不断划分,进行递归。
递归结束的条件为划分到最后若为一个元素则max和min都是这个元素,若为两个取大值赋给max,小值给min。
否则就继续进行划分,找到两个子问题的最大和最小值后,比较这两个最大值和最小值找到解。
2、归并分类使用分治的策略来将一个待排序的数组分成两个子数组,然后递归地对子数组进行排序,最后将排序好的子数组合并成一个有序的数组。
在合并过程中,比较两个子数组的首个元素,将较小的元素放入辅助数组,并指针向后移动,直到将所有元素都合并到辅助数组中。
五、源代码1、找最大和最小元素#include<iostream>using namespace std;void MAXMIN(int num[], int left, int right, int& fmax, int& fmin); int main() {int n;int left=0, right;int fmax, fmin;int num[100];cout<<"请输入数字个数:";cin >> n;right = n-1;cout << "输入数字:";for (int i = 0; i < n; i++) {cin >> num[i];}MAXMIN(num, left, right, fmax, fmin);cout << "最大值为:";cout << fmax << endl;cout << "最小值为:";cout << fmin << endl;return 0;}void MAXMIN(int num[], int left, int right, int& fmax, int& fmin) { int mid;int lmax, lmin;int rmax, rmin;if (left == right) {fmax = num[left];fmin = num[left];}else if (right - left == 1) {if (num[right] > num[left]) {fmax = num[right];fmin = num[left];}else {fmax = num[left];fmin = num[right];}}else {mid = left + (right - left) / 2;MAXMIN(num, left, mid, lmax, lmin);MAXMIN(num, mid+1, right, rmax, rmin);fmax = max(lmax, rmax);fmin = min(lmin, rmin);}}2、归并分类#include<iostream>using namespace std;int num[100];int n;void merge(int left, int mid, int right) { int a[100];int i, j,k,m;i = left;j = mid+1;k = left;while (i <= mid && j <= right) {if (num[i] < num[j]) {a[k] = num[i++];}else {a[k] = num[j++];}k++;}if (i <= mid) {for (m = i; m <= mid; m++) {a[k++] = num[i++];}}else {for (m = j; m <= right; m++) {a[k++] = num[j++];}}for (i = left; i <= right; i++) { num[i] = a[i];}}void mergesort(int left, int right) { int mid;if (left < right) {mid = left + (right - left) / 2;mergesort(left, mid);mergesort(mid + 1, right);merge(left, mid, right);}}int main() {int left=0,right;int i;cout << "请输入数字个数:";cin >> n;right = n - 1;cout << "输入数字:";for (i = 0; i < n; i++) {cin >> num[i];}mergesort(left,right);for (i = 0; i < n; i++) {cout<< num[i];}return 0;}六、运行结果和算法复杂度分析1、找最大和最小元素图1-1 找最大和最小元素结果算法复杂度为O(logn)2、归并分类图1-2 归并分类结果算法复杂度为O(nlogn)实验二背包问题和最小生成树算法实现(用贪心法)一、实验目的1.掌握能用贪心法求解的问题应满足的条件;2.加深对贪心法算法设计方法的理解与应用;3.锻炼学生对程序跟踪调试能力;4.通过本次实验的练习培养学生应用所学知识解决实际问题的能力。
第1篇一、实验目的通过本次实验,掌握常见算法的设计原理、实现方法以及性能分析。
通过实际编程,加深对算法的理解,提高编程能力,并学会运用算法解决实际问题。
二、实验内容本次实验选择了以下常见算法进行设计和实现:1. 排序算法:冒泡排序、选择排序、插入排序、快速排序、归并排序、堆排序。
2. 查找算法:顺序查找、二分查找。
3. 图算法:深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)。
4. 动态规划算法:0-1背包问题。
三、实验原理1. 排序算法:排序算法的主要目的是将一组数据按照一定的顺序排列。
常见的排序算法包括冒泡排序、选择排序、插入排序、快速排序、归并排序和堆排序等。
2. 查找算法:查找算法用于在数据集中查找特定的元素。
常见的查找算法包括顺序查找和二分查找。
3. 图算法:图算法用于处理图结构的数据。
常见的图算法包括深度优先搜索(DFS)、广度优先搜索(BFS)、最小生成树(Prim算法、Kruskal算法)等。
4. 动态规划算法:动态规划算法是一种将复杂问题分解为子问题,通过求解子问题来求解原问题的算法。
常见的动态规划算法包括0-1背包问题。
四、实验过程1. 排序算法(1)冒泡排序:通过比较相邻元素,如果顺序错误则交换,重复此过程,直到没有需要交换的元素。
(2)选择排序:每次从剩余元素中选取最小(或最大)的元素,放到已排序序列的末尾。
(3)插入排序:将未排序的数据插入到已排序序列中适当的位置。
(4)快速排序:选择一个枢纽元素,将序列分为两部分,使左侧不大于枢纽,右侧不小于枢纽,然后递归地对两部分进行快速排序。
(5)归并排序:将序列分为两半,分别对两半进行归并排序,然后将排序好的两半合并。
(6)堆排序:将序列构建成最大堆,然后重复取出堆顶元素,并调整剩余元素,使剩余元素仍满足最大堆的性质。
2. 查找算法(1)顺序查找:从序列的第一个元素开始,依次比较,直到找到目标元素或遍历完整个序列。
算法设计与分析实验报告教师:学号:姓名:实验一:串匹配问题实验目的:(1) 深刻理解并掌握蛮力法的设计思想;(2) 提高应用蛮力法设计算法的技能;(3) 理解这样一个观点: 用蛮力法设计的算法, 一般来说, 经过适度的努力后, 都可以对算法的第一个版本进行一定程度的改良, 改进其时间性能。
三、实验要求:( 1) 实现BF 算法;(2 ) 实现BF 算法的改进算法: KMP 算法和BM 算法;(3 ) 对上述3 个算法进行时间复杂性分析, 并设计实验程序验证分析结果。
#include "stdio.h"#include "conio.h"#include <iostream>//BF算法int BF(char s[],char t[]){ int i; int a; int b; int m,n; m=strlen(s); //主串长度n=strlen(t); //子串长度printf("\n*****BF*****算法\n");for(i=0;i<m;i++){ b=0; a=i; while(s[a]==t[b]&&b!=n){a++; b++; }if(b==n){ printf("查找成功!!\n\n"); return 0;}}printf("找不到%s\n\n",t); return 0; }//前缀函数值,用于KMP算法int GETNEXT(char t[],int b){ int NEXT[10]; NEXT[0]=-1;int j,k; j=0; k=-1; while(j<strlen(t)){if ((k==-1)||(t[j]==t[k])){j++;k++;NEXT[j]=k; }else k=NEXT[k];}b=NEXT[b];return b;}//KMP算法int KMP(char s[],char t[]){int a=0; int b=0;int m,n; m=strlen(s); //主串长度n=strlen(t); //子串长度printf("\n*****KMP算法*****\n");while(a<=m-n){while(s[a]==t[b]&&b!=n){a++;b++; }if(b==n){printf("查找成功!!\n\n");return 0;}b=GETNEXT(t,b);a=a-b;if(b==-1) b++;}printf("找不到%s\n\n",t);return 0; } //滑动距离函数,用于BM算法int DIST(char t[],char c){ int i=0,x=1;int n; n=strlen(t);while(x&&i!=n-1){if(t[i]==c)x=0;else i++;}if(i!=n-1)n=n-1-i;return n; } //BM算法结果分析与体会:glibc里的strstr函数用的是brute-force(naive)算法,它与其它算法的区别是strstr不对pattern(needle)进行预处理,所以用起来很方便。
第1篇一、实验目的1. 理解快速排序算法的基本原理和实现方法。
2. 掌握快速排序算法的时间复杂度和空间复杂度分析。
3. 通过实验验证快速排序算法的效率。
4. 提高编程能力和算法设计能力。
二、实验环境1. 操作系统:Windows 102. 编程语言:C++3. 开发工具:Visual Studio 2019三、实验原理快速排序算法是一种分而治之的排序算法,其基本思想是:选取一个基准元素,将待排序序列分为两个子序列,其中一个子序列的所有元素均小于基准元素,另一个子序列的所有元素均大于基准元素,然后递归地对这两个子序列进行快速排序。
快速排序算法的时间复杂度主要取决于基准元素的选取和划分过程。
在平均情况下,快速排序的时间复杂度为O(nlogn),但在最坏情况下,时间复杂度会退化到O(n^2)。
四、实验内容1. 快速排序算法的代码实现2. 快速排序算法的时间复杂度分析3. 快速排序算法的效率验证五、实验步骤1. 设计快速排序算法的C++代码实现,包括以下功能:- 选取基准元素- 划分序列- 递归排序2. 编写主函数,用于生成随机数组和测试快速排序算法。
3. 分析快速排序算法的时间复杂度。
4. 对不同规模的数据集进行测试,验证快速排序算法的效率。
六、实验结果与分析1. 快速排序算法的代码实现```cppinclude <iostream>include <vector>include <cstdlib>include <ctime>using namespace std;// 生成随机数组void generateRandomArray(vector<int>& arr, int n) {srand((unsigned)time(0));for (int i = 0; i < n; ++i) {arr.push_back(rand() % 1000);}}// 快速排序void quickSort(vector<int>& arr, int left, int right) { if (left >= right) {return;}int i = left;int j = right;int pivot = arr[(left + right) / 2]; // 选取中间元素作为基准 while (i <= j) {while (arr[i] < pivot) {i++;}while (arr[j] > pivot) {j--;}if (i <= j) {swap(arr[i], arr[j]);i++;j--;}}quickSort(arr, left, j);quickSort(arr, i, right);}int main() {int n = 10000; // 测试数据规模vector<int> arr;generateRandomArray(arr, n);clock_t start = clock();quickSort(arr, 0, n - 1);clock_t end = clock();cout << "排序用时:" << double(end - start) / CLOCKS_PER_SEC << "秒" << endl;return 0;}```2. 快速排序算法的时间复杂度分析根据实验结果,快速排序算法在平均情况下的时间复杂度为O(nlogn),在最坏情况下的时间复杂度为O(n^2)。
《算法设计与分析》课程实验报告实验序号:实验项目名称:随机化算法一、实验题目1.N后问题问题描述:在n*n格的棋盘上放置彼此不受攻击的n个皇后,任何两个皇后不放在同一行同一列,同一斜线上,问有多少种放法。
2.主元素问题问题描述:设A是含有n个元素的数组,如果元素x在A中出现的次数大于n/2,则称x是A的主元素。
给出一个算法,判断A中是否存在主元素。
二、实验目的(1)通过N后问题的实现,体会拉斯维加斯随机算法的随机特点:运行次数随机但有界,找到的解一定为正确解。
但某次运行可能找不到解。
(2)通过实现主元素的不同算法,了解蒙特卡罗算法的随机特性:对于偏真的蒙特卡罗算法,找到为真的解一定是正确解;但非真的解以高概率给出解的正确率------即算法找到的非真解以小概率出现错误。
同时体会确定性算法与随机化算法的差异及各自的优缺点。
(3)通过跳跃表的实现,体会算法设计的运用的广泛性,算法设计的思想及技巧不拘泥独立问题的解决,而在任何需要计算机解决的问题中,都能通过算法设计的技巧(无论是确定性还是随机化算法)来灵巧地解决问题。
此实验表明,通过算法设计技巧与数据组织的有机结合,能够设计出高效的数据结构。
三、实验要求(1)N后问题分别以纯拉斯维加斯算法及拉斯维加斯算法+回溯法混合实现。
要求对同一组测试数据,完成如下任务a.输出纯拉斯维加斯算法找到解的运行次数及运行时间。
b.输出混合算法的stopVegas值及运行时间c.比较a、b的结果并分析N后问题的适用情况。
(2)主元素问题,要求对同一组测试数据,完成如下任务:a.若元素可以比较大小,请实现O(n )的确定性算法,并输出其运行时间。
b.(选做题)若元素不可以比较大小,只能比较相同否,请实现O(n) 确性算法,并输出其运行时间。
c.实现蒙特卡罗算法,并输出其运行次数及时间。
d.比较确定性算法与蒙特卡罗算法的性能,分析每种方法的优缺点。
(3)参照教材实现跳跃表(有序)及基本操作:插入一个结点,删除一个结点。
昆明理工大学信息工程与自动化学院学生实验报告( 2011 — 2012 学年 第 1 学期 )课程名称:算法设计与分析 开课实验室:信自楼机房444 2012 年12月 14日一、上机目的及内容1.上机内容给定有n 个整数(可能有负整数)组成的序列(a 1,a 2,…,a n ),求改序列形如∑=jk ka1的子段和的最大值,当所有整数均为负整数时,其最大子段和为0。
2.上机目的(1)复习数据结构课程的相关知识,实现课程间的平滑过渡; (2)掌握并应用算法的数学分析和后验分析方法;(3)理解这样一个观点:不同的算法能够解决相同的问题,这些算法的解题思路不同,复杂程度不同,解题效率也不同。
二、实验原理及基本技术路线图(方框原理图或程序流程图)(1)分别用蛮力法、分治法和动态规划法设计最大子段和问题的算法; 蛮力法设计原理:利用3个for 的嵌套(实现从第1个数开始计算子段长度为1,2,3…n 的子段和,同理计算出第2个数开始的长度为1,2,3…n-1的子段和,依次类推到第n 个数开始计算的长为1的子段和)和一个if (用来比较大小),将其所有子段的和计算出来并将最大子段和赋值给summax1。
用了3个for 嵌套所以时间复杂性为○(n 3);分治法设计原理:1)、划分:按照平衡子问题的原则,将序列(1a ,2a ,…,na )划分成长度相同的两个字序列(1a ,…,⎣⎦2/n a )和(⎣⎦12/+n a ,…,na )。
2)、求解子问题:对于划分阶段的情况分别的两段可用递归求解,如果最大子段和在两端之间需要分别计算s1=⎣⎦⎣⎦)2/1(max2/n i an ik k≤≤∑=,s2=⎣⎦⎣⎦)2/(max12/n j n ajn k k≤≤∑+=,则s1+s2为最大子段和。
若然只在左边或右边,那就好办了,前者视s1为summax2,后者视s2 o summax2。
3)、合并:比较在划分阶段的3种情况下的最大子段和,取三者之中的较大者为原问题的解。
福建师范大学协和学院本科实验报告课程名称:《算法设计与分析》学院(系):专业:班级:学号:学生姓名:学号:学生姓名:学号:学生姓名:实验项目标题前加*号的实验题目为设计实验《算法设计与分析》实验报告填写要求一、本课程共需完成七次实验,由十五个实验项目组成。
每一次实验需在备选项目中选择一个项目完成并提交一份实验报告,批改后下发的实验报告请保存起来,期末上交。
二、实验报告书写要求:1.实验目的和要求:明确实验的内容和具体任务;2.列出源程序,备注说明程序的基本结构,包括程序中各部分的功能。
3.说明程序中各部分所用的算法或原理,计算出算法时间和空间复杂性,并给出计算过程。
4.实验结果与分析:给出不少于3组数据测试算法,并将每组测试数据的运行结果列出,并对调试源程序的结果进行分析,杜绝只罗列不分析;5.讨论、建议、质疑:针对实验中碰到的问题进行组内以及组外讨论,遇到不能解决的问题时向指导老师请教,并将问题的提出以及解决的过程写入实验报告,以作为以后学习的参考。
问题要具体描述,避免抽象地罗列、笼统地讨论;6.全部文字叙述内容要求简明扼要,思路清楚;7.实验日期、同组员姓名写清楚。
三、要求实验报告字迹工整、文字简练、数据齐全、计算正确,分析充分、具体、定量。
对于抄袭实验报告和编篡原始数据的行为,一经发现,以零分处理,并根据相关条例给予处分。
福建师范大学协和学院实验报告实验日期:年月日星期组员姓名:成绩:实验一递归与分治算法实验(一)项目一快速排序(验证实验)一、重要的程序说明(说明程序的基本结构以及程序中各部分的功能,以伪代码和图的形式说明)二、算法复杂性分析与计算(说明程序中各部分所用的算法或原理,计算出算法时间和空间复杂性,并写出计算过程)三、程序运行测试结果分析:四、程序调试过程中遇到的错误,如何讨论、有何建议与质疑五、思考题试想想,这样的排序算法有什么优势?能对所有的数据测试用例都使用这种算法吗?福建师范大学协和学院实验报告实验日期:年月日星期组员姓名:成绩:实验一递归与分治算法实验(一)项目二合并排序(验证实验)一、重要的程序说明(说明程序的基本结构以及部分的功能,以伪代码和图的形式说明)二、算法复杂性分析与计算(说明程序中各部分所用的算法或原理,计算出算法时间和空间复杂性,并写出计算过程)三、程序运行测试结果分析:四、程序调试过程中遇到的错误,如何讨论、有何建议与质疑五、思考题为什么合并排序是思想是基于比较类排序里面最快的,它成功的地方在哪儿?福建师范大学协和学院实验报告实验日期:年月日星期组员姓名:成绩:实验一递归与分治算法实验(一)项目三寻找主元素(设计实验)一、重要的程序说明(说明程序的基本结构以及各部分的功能,以伪代码和图的形式说明)二、算法复杂性分析与计算(说明程序中各部分所用的算法或原理,计算出算法时间和空间复杂性,并写出计算过程)三、程序运行测试结果分析:四、程序调试过程中遇到的错误,如何讨论、有何建议与质疑福建师范大学协和学院实验报告实验日期:年月日星期组员姓名:成绩:实验二递归与分治算法实验(二)项目四递归求排列(验证实验)一、重要的程序说明(说明程序的基本结构以及程序中各部分的功能,以伪代码和图的形式说明)二、算法复杂性分析与计算(说明程序中各部分所用的算法或原理,计算出算法时间和空间复杂性,并写出计算过程)四、程序调试过程中遇到的错误,如何讨论、有何建议与质疑五、思考题试想想,递归思想有什么样的优缺点,在调试过程中,随着数据量的增大,调试过程与结果有没有变化?为什么?实验日期:年月日星期组员姓名:成绩:实验二递归与分治算法实验(二)项目五分治求K大元素(设计实验)一、重要的程序说明(说明程序的基本结构以及部分的功能,以伪代码和图的形式说明)二、算法复杂性分析与计算(说明程序中各部分所用的算法或原理,计算出算法时间和空间复杂性,并写出计算过程)四、程序调试过程中遇到的错误,如何讨论、有何建议与质疑五、思考题这种求K大元素与前面学过的合并排序有无关联?仔细想一想他们的本质。
实验课程名称:算法设计与分析这里的数据包括1到100的所有数字,55在这个序列中。
2.当没找到所要寻找的数字时,输出该数据并不存在于数据库中:0并不存在于这个序列中。
一、时间复杂性分析:1.最好情况下:这里的最好情况,即为第一次查找就找到了要找的数据,故时间复杂性为O (1)。
2.最坏情况下:这里的最坏情况意味着要将所有数据都找一遍最后才能找到要查找的数据,随着数据库的增大,查找次数会随之增长,故其时间复杂度为O (n )。
3.平均情况下:这种情况考虑了数据时等概率的分布于数据库中。
ASL=-101-121111=2=(1*2+2*2+...+*2)log (+1)-1nkj k i i i j p c j k n nn==≈∑∑折半查找的时间复杂性为O (2log n )。
二、空间复杂度分析:这里查找的过程中并不需要额外的空间,只需要存放数据的空间,故空间复杂度为O (n ),n 为数组的大小。
三、算法功能:其功能主要是用来查找数据,若对它进行一下拓展,可以由自主确定数据库,并可对他进行操作;这里的数据也可以不只是包括整数。
实验二结果:1.当数组的容量不大于0时,显示错误:2.当输入数据错误时,显示错误:3.当输入正确时的显示结果:一、时间复杂性分析:1.最好情况下:T (n )≤2 T (n /2)+n ≤2(2T (n /4)+n /2)+n =4T (n /4)+2n ≤4(2T (n /8)+n /4)+2n =8T (n /8)+3n … … …≤nT (1)+n log 2n =O (n log 2n ) 因此,时间复杂度为O (n log 2n )。
2.最坏情况下:待排序记录序列正序或逆序,每次划分只得到一个比上一次划分少一个记录的子序列(另一个子序列为空)。
此时,必须经过n -1次递归调用才能把所有记录定位,而且第i 趟划分需要经过n -i 次关键码的比较才能找到第i 个记录的基准位置,因此,总的比较次数为: 因此,时间复杂度为O (n 2)。
算法设计与分析实验报告1. 引言本实验报告旨在介绍算法设计与分析的相关内容。
首先,我们将介绍算法设计的基本原则和步骤。
然后,我们将详细讨论算法分析的方法和技巧。
最后,我们将通过一个实例来演示算法设计与分析的过程。
2. 算法设计算法设计是解决问题的关键步骤之一。
它涉及确定问题的输入和输出,以及找到解决方案的具体步骤。
以下是算法设计的一般步骤:2.1 理解问题首先,我们需要全面理解给定问题的要求和约束。
这包括确定输入和输出的格式,以及问题的具体要求。
2.2 制定算法思路在理解问题后,我们需要制定解决问题的算法思路。
这涉及确定解决问题的高层次策略和步骤。
通常,我们使用流程图、伪代码等工具来表示算法思路。
2.3 编写算法代码在制定算法思路后,我们可以根据思路编写实际的算法代码。
这可能涉及选择适当的数据结构和算法,以及编写相应的代码来实现解决方案。
2.4 调试和测试编写算法代码后,我们需要进行调试和测试,以确保算法的正确性和可靠性。
这包括检查代码中可能存在的错误,并使用不同的测试样例来验证算法的正确性。
3. 算法分析算法分析是评估算法性能的过程。
它涉及确定算法的时间复杂度和空间复杂度,以及评估算法在不同输入情况下的执行效率。
3.1 时间复杂度时间复杂度是衡量算法执行时间随输入规模增长的速度。
常见的时间复杂度包括常数时间复杂度 O(1)、线性时间复杂度 O(n)、对数时间复杂度 O(log n)、平方时间复杂度 O(n^2) 等。
通过分析算法中的循环、递归等关键部分,可以确定算法的时间复杂度。
3.2 空间复杂度空间复杂度是衡量算法所需空间随输入规模增长的速度。
它通常用于评估算法对内存的使用情况。
常见的空间复杂度包括常数空间复杂度 O(1)、线性空间复杂度 O(n)、对数空间复杂度 O(log n) 等。
通过分析算法中的变量、数组、递归栈等关键部分,可以确定算法的空间复杂度。
3.3 执行效率评估除了时间复杂度和空间复杂度外,我们还可以通过实验和测试来评估算法的执行效率。
算法设计与分析实验报告1. 引言本实验旨在设计和分析一个算法,解决特定的问题。
通过对算法的设计、实现和性能分析,可以对算法的优劣进行评估和比较。
本报告将按照以下步骤进行展开:1.问题描述2.算法设计3.算法实现4.性能分析5.结果讨论和总结2. 问题描述在本实验中,我们面临的问题是如何在一个给定的无序数组中寻找一个特定元素的位置。
具体而言,给定一个包含n个元素的数组A和一个目标元素target,我们的目标是找到target在数组A中的位置,如果target不存在于数组中,则返回-1。
3. 算法设计为了解决上述问题,我们设计了一个简单的线性搜索算法。
该算法的思想是从数组的第一个元素开始,逐个比较数组中的元素与目标元素的值,直到找到匹配的元素或搜索到最后一个元素。
算法的伪代码如下:function linear_search(A, target):for i from 0 to len(A)-1:if A[i] == target:return ireturn -14. 算法实现我们使用Python编程语言实现了上述线性搜索算法。
以下是算法的实现代码:def linear_search(A, target):for i in range(len(A)):if A[i] == target:return ireturn-15. 性能分析为了评估我们的算法的性能,我们进行了一系列实验。
我们使用不同大小的数组和不同目标元素进行测试,并记录了每次搜索的时间。
实验结果显示,线性搜索算法的时间复杂度为O(n),其中n是数组的大小。
这是因为在最坏的情况下,我们需要遍历整个数组才能找到目标元素。
6. 结果讨论和总结通过对算法的设计、实现和性能分析,我们可以得出以下结论:1.线性搜索算法是一种简单但有效的算法,适用于小规模的数据集。
2.线性搜索算法的时间复杂度为O(n),在处理大规模数据时可能效率较低。
3.在实际应用中,我们可以根据具体的问题和数据特征选择合适的搜索算法,以提高搜索效率。
本科实验报告课程名称:算法设计与分析实验项目:递归与分治算法实验地点:计算机系实验楼110专业班级:物联网1601 学号:2016002105 学生:俞梦真指导教师:郝晓丽2018年05月04 日实验一递归与分治算法1.1 实验目的与要求1.进一步熟悉C/C++语言的集成开发环境;2.通过本实验加深对递归与分治策略的理解和运用。
1.2 实验课时2学时1.3 实验原理分治(Divide-and-Conquer)的思想:一个规模为n的复杂问题的求解,可以划分成若干个规模小于n的子问题,再将子问题的解合并成原问题的解。
需要注意的是,分治法使用递归的思想。
划分后的每一个子问题与原问题的性质相同,可用相同的求解方法。
最后,当子问题规模足够小时,可以直接求解,然后逆求原问题的解。
1.4 实验题目1.上机题目:格雷码构造问题Gray码是一个长度为2n的序列。
序列无相同元素,每个元素都是长度为n的串,相邻元素恰好只有一位不同。
试设计一个算法对任意n构造相应的Gray码(分治、减治、变治皆可)。
对于给定的正整数n,格雷码为满足如下条件的一个编码序列。
(1)序列由2n个编码组成,每个编码都是长度为n的二进制位串。
(2)序列中无相同的编码。
(3)序列中位置相邻的两个编码恰有一位不同。
2.设计思想:根据格雷码的性质,找到他的规律,可发现,1位是0 1。
两位是00 01 11 10。
三位是000 001 011010 110 111 101 100。
n位是前n-1位的2倍个。
N-1个位前面加0,N-2为倒转再前面再加1。
3.代码设计:}}}int main(){int n;while(cin>>n){get_grad(n);for(int i=0;i<My_grad.size();i++)cout<<My_grad[i]<<endl;My_grad.clear();}return 0;}运行结果:1.5 思考题(1)递归的关键问题在哪里?答:1.递归式,就是如何将原问题划分成子问题。
《算法设计与分析》实验报告班级姓名学号2014年 11月 18日目录实验一二分查找程序实现………………………………………………………………01页实验二棋盘覆盖问题…………………………………………………………………04页实验三 0-1背包问题的动态规划算法设计……………………………………….07页实验四背包问题的贪心算法………………………………………………………10页指导教师对实验报告的评语成绩:指导教师签字:年月日实验一:二分查找程序的实现实验时间:2014年11月13日,星期四第三、四节,地点:J13#328二、实验目的及要求1)、实验目的:1. 掌握分治算法的基本思想(分—治—合)、技巧和效率分析方法。
2. 熟练掌握用递归设计分治算法的基本步骤。
3. 学会分治算法解决实际问题。
2)、实验要求:实现二分搜索的递归与非递归程序,并进行跟踪分析其执行过程,体会两者的执行效率。
三、实验环境Windows 2008C++四、实验内容实现二分搜索的递归与非递归程序,并进行跟踪分析其执行过程,体会两者的执行效率。
将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。
如果x<a[n/2],则我们只要在数组a的左半部分继续搜索x。
如果x>a[n/2],则我们只要在数组a的右半部分继续搜索x。
直到找到x,并返回x所在数组中的下标。
五、算法描述及实验步骤它的基本思想是,将n个元素分成个数大致相同的两半,取a[n/2]与欲查找的x作比较,如果x=a[n/2]则找到x,算法终止。
如果x<a[n/2],则我们只要在数组a的左半部继续搜索x(这里假设数组元素呈升序排列)。
如果x>a[n/2],则我们只要在数组a的右半部继续搜索xint BinarySearch(int a[],int x,int n){//非递归方法int left=0;int right=n-1;while(left<=right){int middle=(left+right)/2;if (x==a[middle]) return middle;if (x>a[middle]) left=middle+1;else right=middle-1;}return -1;}//递归int BinSearch(int a[],int x,int low,int high){int mid;while(low<=high){mid=(low+high)/2;if(x==a[mid]) return mid;if(x<a[mid]) return(BinSearch(a,x,low,mid-1)); else return(BinSearch(a,x,mid+1,high));}return -1;}算法复杂性分析:容易看出,每执行一次算法的while循环,待搜索数组的大小减少一半。