第三章实践上机报告

实践报告任选一题进行分析。内容包括:

  1. 实践题目
  2. 问题描述
  3. 算法描述
  4. 算法时间及空间复杂度分析(要有分析过程)
  5. 心得体会(对本次实践收获及疑惑进行总结)

 

1.实践题目:编辑距离问题

2.问题描述:设A和B是2个字符串。要用最少的字符操作将字符串A转换为字符串B。这里所说的字符操作包括 (1)删除一个字符; (2)插入一个字符; (3)将一个字符改为另一个字符。 将字符串A变换为字符串B所用的最少字符操作数称为字符串A到 B的编辑距离,记为d(A,B)。 对于给定的字符串A和字符串B,计算其编辑距离 d(A,B)。

3.算法描述:其实这个题目讲了这么多,解题无非就是用到一个核心算法:求最长公共子序列,我们先要求这两个序列的最长公共子序列,因为这些序列是不用修改的,剩下的要修改的次数就是AB序列的长度差加上最长公共子序列与B序列即目的序列的差。所以我们关键要写好最长公共子序列的算法就ok了。

最长公共子序列:递归公式

4.算法时间复杂度和空间复杂度:

int LCSLength(char* str1, char* str2, int length1,int length2)
{
int i,j,len;
//length1 = strlen(str1);
//length2 = strlen(str2);

//双指针的方法申请动态二维数组
int **c = new int*[length1+1]; //共有length1+1行
for(i = 0; i < length1+1; i++)
c[i] = new int[length2+1];//共有length2+1列

for(i = 0; i < length1+1; i++)
c[i][0]=0; //第0列都初始化为0
for(j = 0; j < length2+1; j++)
c[0][j]=0; //第0行都初始化为0

for(i = 1; i < length1+1; i++)
{
for(j = 1; j < length2+1; j++)
{
if(str1[i-1]==str2[j-1])//由于c[][]的0行0列没有使用,c[][]的第i行元素对应str1的第i-1个元素
{
c[i][j]=c[i-1][j-1]+1;
//b[i][j]=0; //输出公共子串时的搜索方向
}
else if(c[i-1][j]>c[i][j-1])
{
c[i][j]=c[i-1][j];
// b[i][j]=1;
}
else
{
c[i][j]=c[i][j-1];
// b[i][j]=-1;
}
}
}
len=c[length1][length2];
//cout<<len<<endl;
return len;
}

时间复杂度为O(mn),LCSLength算法以AB两个序列为输入,输出最大公共子序列长度len。其中c[i][j]是用来存储len的,最优值则放在c[m][n]中,每个数组单元的计算耗费为O(1)时间,算法LCSLength的总耗费为O(mn)。因为要给算法开辟一个c数组的空间,而c数组空间为m*n,所以空间复杂度也为O(mn)。

5.心得体会(对本次实践收获及疑惑进行总结)

这次编程实践题目还算基础,也有相关类似的题目,但是我和同学编程的时候都遇到过一个越界问题。例如第一题

for(int i=row-1;i>0;i--)
for(int j=1;j<=i;j++)
{
if(a[i+1][j]>=a[i+1][j+1])
{
a[i][j]+=a[i+1][j] ;
}
else
a[i][j]+=a[i+1][j+1] ;
}

第一行代码的int i=row-1,虽然说int i=row答案也一样,因为我们取得数组空间较大,越界后取出来的值是0,并不影响答案,但是不能这样,因为范围设为row后,后面就有a[row+1][],显然这个是不存在的,最大应该是a[row][],所以初始i应为row-1.

所以以后处理数组要处理好数组的范围问题。

posted @ 2018-11-01 09:48  荷里活DJ  阅读(105)  评论(0编辑  收藏  举报