中北大学软件学院算法分析与设计实验报告Word下载.docx
《中北大学软件学院算法分析与设计实验报告Word下载.docx》由会员分享,可在线阅读,更多相关《中北大学软件学院算法分析与设计实验报告Word下载.docx(34页珍藏版)》请在冰豆网上搜索。
![中北大学软件学院算法分析与设计实验报告Word下载.docx](https://file1.bdocx.com/fileroot1/2022-10/4/c2b746fd-b162-4980-99f3-ceebbb2696bb/c2b746fd-b162-4980-99f3-ceebbb2696bb1.gif)
实验时间
2016年4月7日8时至10时
学时数
2
1.实验名称
实验一串匹配程序设计
2.实验目的
(1)熟练掌握串匹配的含义
(2)掌握BF算法匹配的过程并编程实现
(3)熟悉C++编译环境的基本操作
3.实验内容
给定两个字符串S和T,用BF算法,在主串S中查找字串T,输出结果,输出时要求有文字说明。
请编写程序。
4.实验原理或流程图
基本思想:
从主串S的第一个字符开始和模式T的第一个字符进行比较,若相等,则继续比较两者的后续字符;
若不相等,则从主串S的第二个字符开始和模式T的第一个字符进行比较,重复上述过程,若T中的字符全部比较完毕,则说明本趟匹配成功;
若最后一轮匹配的起始位置是n-m,则主串S中剩下的字符不足够匹配整个模式T,匹配失败。
这个算法称为朴素的模式匹配算法,简称BF算法。
设串S长度为n,串T长度为m,在匹配成功的情况下,考虑最坏情况,即每趟不成功的匹配都发生在串T的最后一个字符。
设匹配成功发生在si处,则在i-1趟不成功的匹配中共比较了(i-1)×
m次,第i趟成功的匹配共比较了m次,所以总共比较了i×
m次,因此平均比较次数是:
最坏情况是O(n×
m)。
或者写书上P39页的伪代码描述。
5.实验过程或源代码
#include<
stdio.h>
intBF(charS[],charT[]){
intindex=0;
//主串从下标0开始第一趟匹配
inti=0,j=0;
//设置比较的起始下标
while((S[i]!
='
\0'
)&
&
(T[j]!
)){//模式匹配没有结束
printf("
->
从主串的第%d个位置开始与模式串进行匹配:
(只输出回溯信息)\n"
i);
if(S[i]==T[j]){//相同位置字符相同
i++;
j++;
//向后匹配
}
else{//相同位置字符不同
printf("
由于主串下标i为%d的字符%c和模式串下标j为%d的字符%c失配"
i,S[i],j,T[j]);
index++;
i=index;
j=0;
//i和j分别回溯
printf("
所以i和j分别回溯到%d,%d重新开始匹配\n"
i,j);
}
}
if(T[j]=='
)
returnindex+1;
//返回本趟匹配的开始位置(不是下标)
else
return0;
}
intmain(){
charS[100],T[100];
printf("
请输入主串S(不超过100个字符):
"
);
scanf("
%s"
S);
请输入子串T(不超过100个字符):
T);
intindex=BF(S,T);
if(index==0){
printf("
模式匹配失败!
}
else{
模式匹配成功,子串%s在主串%s中首次匹配的位置是%d"
T,S,index);
return0;
}
6.实验结论及心得
通过本次实验我理解了使用蛮力法解决问题的特点,蛮力法的设计思想是直接基于问题本身的描述来设计算法,即不采用任何方法来精简计算过程、运算次数或者设法简化问题本身。
所以蛮力法设计的算法虽然简单易懂,但是效率却往往不是很令人满意,比如串的模式匹配问题中采用BF算法效率低下的主要原因就在于BF算法一旦主串和子串匹配失败就会产生回溯,如果能利用已有的匹配结果来减少回溯就可以提高效率,如KMP算法。
实验二排序问题程序设计
(1)掌握选择排序和起泡排序的基本思想
(2)掌握两种排序方法的具体实现过程
(3)在掌握的基础上编程实现两种排序方法
输入一个待排序的序列,分别用选择排序和起泡排序两种排序方法将其变换成有序的序列,输出结果,输出时要求有文字说明。
书上P42页选择排序想法三点抄上去
书上P43页冒泡排序想法三点抄上去
//----------------------------选择排序----------------------------------
//对含有n个数的数组进行遍历
voidvisit(intr[],intn){
for(inti=0;
i<
n;
i++)
%4d"
r[i]);
\n"
//选择排序
voidSelectSort(intr[],intn){
inti,j,index,temp;
intcompare=0,move=0;
for(i=0;
i<
n-1;
i++){ //对n个记录进行n-1趟选择排序
index=i;
for(j=i+1;
j<
n;
j++){//在无序区中查找最小记录
if(r[j]<
r[index])
index=j;
compare++;
//比较次数增加1
}
if(index!
=i){//交换记录
temp=r[i];
r[i]=r[index];
r[index]=temp;
move+=3;
//交换一次移动3次
visit(r,10);
在本次排序中共比较了%d次,移动了%d次。
compare,move);
intr[10]={0};
请依次输入10个整数,用空格隔开:
10;
scanf("
%d"
&
r[i]);
排序之前的记录:
visit(r,10);
进行选择排序:
(每趟排序后的结果如下所示)\n"
SelectSort(r,10);
排序之后的记录:
#include<
voidBubbleSort(intr[],intn){
intcount1=0,count2=0;
//count1和count2记载比较次数和移动次数
intbound,exchange=n-1;
//第一趟起泡排序的区间是[0,n-1]
while(exchange!
=0){//当上一趟排序有记录交换时
bound=exchange;
exchange=0;
for(intj=0;
bound;
j++)//一趟起泡排序区间是[0,bound]
if(++count1&
r[j]>
r[j+1]){//注意不能写作count1++
inttemp=r[j];
r[j]=r[j+1];
r[j+1]=temp;
count2=count2+3;
//1次交换是3次移动操作
exchange=j;
//记载每一次记录交换的位置
}
//每趟排序输出一次,观察记录的变动情况
本次排序中的比较次数为%d,移动次数为%d。
count1,count2);
进行冒泡排序:
BubbleSort(r,10);
通过本次实验我理解了选择排序和起泡排序的基本思想。
选择排序和起泡排序都是通过将待排序记录划分成有序区和无序区,然后通过交换扩大有序区,缩小无序区,最终达到排序的目的。
两者又有区别,选择排序可以直接选出无序区的最小记录并一次插入到合适的位置上,之后不再调整,而冒泡排序则是通过两两交换实现移动的,由于很多移动无法将记录一次放置到合适的位置上,所以存在很多“无效”的移动操作,从实验结果可以看出,起泡排序的移动次数明显比选择排序要多就是因为这样的“无效”的移动操作浪费了时间。
实验三数字旋转方阵程序设计
(1)掌握分治法的设计思想
(2)掌握数字旋转方阵的具体实现过程
(3)熟练掌握二维数组的使用方法
(4)在掌握的基础上编程实现数字旋转方阵的实现过程
给出一个初始数据,在此数据的基础上由外层向里层填写数据,完成一个数字旋转方阵