大学算法分析与设计复习总结

3-3 对于KMP算法中求next数组问题,设计一个蛮力算法,并分析其时间性能。

voidGetNext(char T[ ], int next[ ])

{

next[1]=0;

next[2]=1;

j=T[0],k=0;

for(;j>2;j–){

for(n=j-2;n>=1;n–){//n为要比较的前缀的最后一个字符的下标

m=j-n;//m为要比较的后缀的第一个字符的下标

for(i=1;i<=n;i++)

{

if(T[i]!=T[m+i-1])break;

}

if(i==n+1){next[j]=n+1;break;}

}

if(n==0)next[j]=1;

}

}

3-4 假设在文本“ababcabccabccacbab”中查找模式 “abccac”,求分别采用BF算法和KMP算法进行串匹配过程中的字符比较次数。

**

**

由此可知,用BF算法一共要进行3+1+4+1+1+6+1+1+1+6=25次比较方能匹配出

KMP算法:next[]={,0,1,1,1,1,2};

由此可知,用KMP算法一共要进行3+4+6+5=18次比较方能匹配出

参考代码如下:

排列最终存储在长度为n的阶乘,元素类型为指针的数组中,数组指向一个排列,具体的排列数据存储在数组中。

int fabs(int n)

{

int r=1;

for(inti=n;i>1;i–)

r=r*i;

return r;

}

//排列存储在数组中

void getArrangement(int**&s,int n)

{

int * p,*q;

int * *s1;

int i,j,k,l,m,o;

s=new int *[1];

s[0]=newint[1];

s[0][0]=1;

for(i=2;i<=n;i++)

{

j=0;

o=0;

m=fabs(i-1);

s1=newint *[fabs(i)];

while(o<m)

{

q=p=s[o];

for(k=i-1;k>=0;k–)

{

s1[j]=newint[i];

for(l=0;l<i;l++)

{

if(l==k){s1[j][l]=i;}

else{

s1[j][l]=*p;

p++;}

}

j++;

p=q;

}

o++;

delete[] q;

}

delete[]s;

s=s1;

}

}

3-8对于一个平面上n个点的集合S,设计蛮力算法求集合S的凸包的一个极点。

点集合中最左边或者最右边的点一定是凸包的一个极点,则求凸包的极点的问题转化为求点的x坐标最大或最小的点

int getPole(int x[],int y[],int n)

{

int r=0;

for(inti=0;i<n;i++)

{

if(x[i]>x[r])r=i;

}

return r;

}

3-11 设计算法生成在n个元素中包含k个元素的所有组合对象。

两种思路:

1、  生成所有的组合,在组合中找元素个数为k个的组合。

伪代码:

1.初始化一个长度为n的比特串s=00…0并将对应的子集输出;

2.for(i=1; i<2n; i++)   //注意不能书写成i<=2n

2.1  s++;

2.2  判断s中1的个数,若为k,则将s对应的子集输出;

2、  使用k层嵌套循环生成元素个数为k个的组合。

设k=3;n个元素存储在数组a[]中;

伪代码:

for (i=1; i<n-2; i++)

for(j=i+1; i<n-1; i++)

for(k=j+1; i<n; i++)

输出a[i]a[j]a[k]构成的组合。

3-13美国有个连锁店叫7-11这个连锁店以前是每天7点开门,晚上11点关门

不过现在是全天24小时营业。有一天,有个人来到这个连锁店,买了4件商品

营业员拿起计算器敲了一下,说:总共是$7.11顾客开玩笑说:所以你们商店就叫7-11?营业员没有理她,说:当然不是,我是把它们的价格相乘之后得到的。

顾客说:相乘?你应该把他相加才对。营业员说,我弄错了。接着又算了一遍,结果让两个人吃惊的是:计算结果也是$7.11请问,这4件商品的价格是多少?

参考代码:

#include<iostream.h>

#include <stdio.h>

int main()

{

long i,j,k,m;

for (i=1; i <=711/4 ; i++)

{

for (j=i; j <=711/3 ; j++)

{

for (k=j; k <=711/2 ; k++)

{

m=711-i-j-k;

if (ijkm==7111000000)

{

cout<<i<<endl<<j<<endl<<k<&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值