• 5.11返校测试T4


    (因为此题知识没太掌握,借鉴一下CYC大佬的题解)

    原文链接:https://www.cnblogs.com/Cao-Yucong/p/12876555.html

    题4:字符串的修改(str.cpp/in/out)

    题目描述:

    有 A=a1a2a3……am,B=b1b2b3……bn 两个字符串(均为小写字母)现在要通过以下操作将 A 或 A 的一个后缀修改为 B: 1. 删除 删除掉 A 中的某一个字符。 2. 添加 将某一个字符添加到 A 中任意位置。 3. 替换 将 A 中某一字符替换为另一个。 求出最小操作次数。

    输入格式

    第一行为字符串 A。第二行为字符串 B(长度均不超过 1000)。

    输出格式

    一个正整数,最小操作次数。

    输入样例

    aaab
    aabc
    

    输出样例

    1
    

    思路

    动态规划,f[i][j]表示a的前i位和b的前j位对齐,需要的最少操作次数。最终需要得到的答案就是f[m][n],即的前m位和b的前n位对齐所需要的最少操作数量。初始状态有下面两种:

    f[i][0]=0f[0][i]=i

    分别表示a的前i位和b的前0位(也就是什么都没有)对齐需要的最少操作数量,以及a的前0位和b的前i位对齐所需要的操作次数(也就是在a的前面加入i个数,操作次数是n)。

    另外需要注意的就是,我们输入的是字符串a、b是从0到m-1,0到n-1存储的,输入之后需要把整个字符数组向后移一位。并且因为字符串长度过长,需要用char数组存储。

    状态转移方程是这样的:

    f[i][j]=min(f[i−1][j]+1,f[i][j−1]+1,f[i−1][j−1]+com(a[i],b[j]))

    前两个的含义是:如果想把a的前i位和b的前j位对齐,我们可以找a的前i-1位已经和b的前j位对齐的操作次数,再用一次操作把这个字符串“平移”一下得到。怎么平移?根据题目给的条件,如果a的前i-1位已经和b的前j位对齐,那我在a的最前面添加一个数字,第i-1位就变成第i位了。这种操作在逻辑上讲和平移是一样的。

    第三个的含义是:如果想把a的前i位和b的前j位对齐,我们可以找a的前i-1位已经和b的前j-1位对齐的操作次数,再判断一下a[i]和b[j]是否相等,如果相等,就不需要操作;如果不相等,就操作数+1。(com函数就是用来判断这个的。)

    代码

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    int f[1009][1009];
    char a[1099],b[1099];//string字符串会爆,所以必须用char数组
    int strlen(char x[]){//手写字符串长度函数
    	int tot = 0;
    	while(x[tot++] != '');
    	tot--;
    	return tot;
    }
    int com(int x,int y){//如果相同返回0,不同就返回1
    	if(a[x] == b[y]) return 0;
    	return 1;
    }
    int main(){
    	cin >> a >> b;
    	int m = strlen(a),n = strlen(b);
    	for(int i = max(m,n);i >= 1; i--){
    		a[i] = a[i-1];
    		b[i] = b[i-1];
    	}
    	for(int i = 0;i <= m; i++){
    		f[i][0] = 0;//a的前i位和b的前0位对齐
    	}
    	for(int i = 0;i <= n; i++){
    		f[0][i] = i;//a的前0位和b的前i位对齐
    	}
    	for(int i = 1;i <= m; i++) {
    		for(int j = 1;j <= n; j++){
    			f[i][j] = min(f[i-1][j] + 1,min(f[i][j-1] + 1, f[i-1][j-1] + com(i,j)));
    			//状态转移
    		}
    	}  
    	cout << f[m][n] << endl;
    	return 0;
    } 
    
  • 相关阅读:
    shell中$0,$?,$!等的特殊用法【转载】
    Hadoop操作hdfs的命令【转载】
    libevent的简单应用【转载】
    使用GDB生成coredump文件【转载】
    常用的js代码
    强大的promise
    循环的N种写法
    原型与继承与class
    模块化
    正则RegExp
  • 原文地址:https://www.cnblogs.com/Kyriech-Francis/p/Answer_20200511_T4.html
Copyright © 2020-2023  润新知