回溯法

应用回溯法时,解空间往往以树的结构表示。回溯法以深度优先的方式搜索解空间树。如果回溯法在执行过程中判断解空间树的某个节点不包含问题的解时,则跳过对以该节点为根的子树的搜索,逐层向其祖先节点回溯;否则进入该子树,继续按深度优先策略搜索。
回溯法的搜索过程如下:从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。这个开始结点就成为一个活结点,同时也成为当前的扩展结点。在当前的扩展结点处,搜索向纵深方向移至一个新结点。这个新结点就成为一个新的活结点,并成为当前扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前扩展结点就成为死结点。

此时,应往回移动(回溯)至最近的一个活结点处,并使这个活结点成为当前的扩展结点。回溯法即以这种工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已没有活结点时为止。简单来讲回溯法的基本思想就是:从一条路往前走,能进则进,不能进则退回来,换一条路再试。

编辑距离

两个字符串之间,由一个转成另一个所需的最少编辑操作次数,设A和B是两个字符串,允许的字符操作包括:
(1)添加一个字符
(2)删除一个字符
(3)修改一个字符
要用最少的字符操作将字符串A转换为字符串B。
编辑距离d(A,B)的定义是把一个字符串A通过“插入、删除和替换”这样的编辑操作编程另外一个字符串操作变成另外一个字符串(B)所需要的最少编辑次数(代价或者费用最低)。从另外一个角度来看,可以将“字符串之间的编辑距离”视为“字符串之间的相似度”(和“最长公共子序列”问题有相同的视角),也即“编辑距离”是将一个字符串转换成另外一个字符串的代价(转换的方法可能不唯一),转换的代价越高则说明两个字符串的编辑距离越大,从而其相似度越低。
操作变成另外一个字符串(B)所需要的最少编辑次数(代价或者费用最低)。从另外一个角度来看,可以将“字符串之间的编辑距离”视为“字符串之间的相似度”(和“最长公共子序列”问题有相同的视角),也即“编辑距离”是将一个字符串转换成另外一个字符串的代价(转换的方法可能不唯一),转换的代价越高则说明两个字符串的编辑距离越大,从而其相似度越低.



可以判定,字符串 SNOWY 和 SUNNY 之间的编辑距离为 3。

解:
编辑距离问题的最优子结构性质
编辑距离问题需要多个步骤处理。对字符串 A 做最少修改步骤变换到字符串 B,每个步骤都不是独立的,受前面已经确定的步骤和后面可选步骤的共同影响。设字符串 A 有 m 个字符,字符串 B 有 n 个字符。假定已经得到将 A 的 1 ~ m 个字符转换为 B 的 1 ~ n 个字符所需要的最优解,即最少编辑次数;那么其子问题“将 A 的 1 ~ i 个字符转换为 B 的 1 ~ j 个字符”也一定是最优的,否则的话(反证法),存在一个子问题的最优解,从而导致整个问题有一个更少的编辑次数,这和已知的最优解矛盾。所以编辑距离存在最优子结构性质。

建立状态方程





代码


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>using namespace std;#define STR_LEN           100
#define TRUE              1
#define FALSE             0int  FindTripleMin( int a, int b, int c );
int  CalcEditDistance( char *StrA, char *StrB, int **d );
void PrintEditDistanceMatrix( int **d, int RowNum, int ColNum );char StrA[ STR_LEN ];
char StrB[ STR_LEN ];
int  d[STR_LEN][STR_LEN];
int pp[STR_LEN][STR_LEN];int FindTripleMin( int a, int b, int c )
{int t = ( a < b ) ? a : b;return ( ( t < c ) ? t : c );
}// ( 1 ) A = fxpimu  B = xwrs  d( A, B ) = 5
// ( 2 ) A = abc     B = cba   d( A, B ) = 2
// ( 3 ) A = stot    B = stop  d( A, B ) = 1
// ( 4 ) A = cd      B = abcb  d( A, B ) = 3
int CalcEditDistance()
{for( int i = 0; i <= strlen( StrA ); i++ )d[ i ][ 0 ] = i;for( int j = 0; j <= strlen( StrB ); j++ )d[ 0 ][ j ] = j;for( int i = 1; i <= strlen( StrA ); i++ ){for( int j = 1; j <= strlen( StrB ) ; j++){char x = StrA[i-1];char y = StrB[j-1];if(x == y){d[i][j] =d[i-1][j-1] + 0;}else{d[i][j] = FindTripleMin(d[i][j-1]+1 , d[i-1][j] + 1 , d[i-1][j-1] + 1);}}}return d[ strlen( StrA ) ][ strlen( StrB ) ];
}int FindBack(){int m = strlen( StrA );int n = strlen( StrB );while (n>=0 || m>=0){if (n && d[m][n-1]+1 == d[m][n]){//printf("%d " ,m);printf("\t插入 %c\n" , (StrB[n-1]));n -= 1;continue;}if (m && d[m-1][n]+1 == d[m][n]){//printf("%d " ,m);printf("\t删除 %c\n" , (StrA[m-1]));m -= 1;continue;}if (d[m-1][n-1]+1 == d[m][n]){//printf("%d " ,m);printf("\t替换 %c ---  %c\n" , StrA[m-1],StrB[n-1]);n -= 1;m -= 1;continue;}if (d[m-1][n-1] == d[m][n]){n -= 1;m -= 1;}}}void PrintEditDistanceMatrix(int RowNum, int ColNum )
{int i, j;printf( "\t编辑距离矩阵是 : \n" );for ( i = 0; i <= RowNum - 1; i++ ){printf( "\t" );for ( j = 0; j <= ColNum - 1; j++ )printf( "%d ", d[ i ][ j ] );printf( "\n" );}printf( "\n\n" );
}int main(void)
{int  i, m, n, dAB;system( "cls" );printf( "\n\n\t输入字符串A  : " );//cin >> StrA ;scanf( "%s", StrA );m = strlen( StrA );printf( "\n\t输入字符串B: : " );getchar();//cin >> StrB ;scanf( "%s", StrB );n = strlen( StrB );dAB = CalcEditDistance();FindBack();cout << "\t编辑距离: " << dAB <<endl;PrintEditDistanceMatrix(( m + 1 ), ( n + 1 ) );for ( i = 0; i <= m; i++ )free( d[ i ] );free( d );return 0;}//

使用回溯法解决编辑距离问题(C语言)相关推荐

  1. 回溯算法背包问题迭代c语言,回溯法解决0_1背包问题(迭代和递归)

    问题:0/1背包问题 例子:weight数组代表物品重量,value数组代表物品价值,M代表背包容量.背包是按单位价值递减的顺序排列的,即value[i]/weight[i]>value[i-1 ...

  2. c语言 用回溯算法解决01背包问题,回溯法解决01背包问题

    <回溯法解决01背包问题>由会员分享,可在线阅读,更多相关<回溯法解决01背包问题(21页珍藏版)>请在人人文库网上搜索. 1.回溯法解决01背包问题,回溯法解决01背包问题, ...

  3. 利用回溯法解决1-9之间添加+或-或使得运算结果为100的问题

    问题描述 编写一个在1,2,-,9(顺序不能变)数字之间插入+或-或什么都不插入,使得计算结果总是100的程序,并输出所有的可能性.例如:1 + 2 + 34 – 5 + 67 – 8 + 9 = 1 ...

  4. 回溯法解决0-1背包问题

    回溯法解决0-1背包问题 参考文章: (1)回溯法解决0-1背包问题 (2)https://www.cnblogs.com/womendouyiyang/p/10957527.html (3)http ...

  5. 编程解决素数环问题Java_回溯法解决素数环问题java实现

    素数环问题: 输入正整数n,把整数1,2,3--,n组成一个环,使得相邻两个整数之和均为素数,输出所有方案,注意同一个环应恰好输出一次.n<==16 样例输入: 6 样例输出: 1 4 3 2  ...

  6. 回溯法解决部落冲突问题

    回溯法解决部落冲突问题 实验内容 问题描述 思路分析 方法步骤 实验代码 实验内容 原始部落byteland中的居民为了争抢有限的资源,经常发生冲突.几乎每个居民都有它的仇敌.部落酋长为了组织一支保卫 ...

  7. 回溯法解决n皇后问题

    回溯法解决n皇后问题 题目要求: 在n×n格的棋盘上放置彼此不受攻击的n个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n后问题等价于在n×n格的棋盘上放置n个皇后, ...

  8. 回溯法解决力扣79题单词搜索

    回溯法解决力扣79题单词搜索 给定一个 m x n 二维字符网格 board 和一个字符串单词 word .如果 word 存在于网格中,返回 true :否则,返回 false . 单词必须按照字母 ...

  9. 回溯法解决工作分配问题

    回溯法解决工作分配问题 问题描述: 设有n件工作分配给n个人.为第i个人分配工作j所需的费用为c[i][j] .试设计一个算法,计算最佳工作分配方案,为每一个人都分配1 件不同的工作,并使总费用达到最 ...

最新文章

  1. c语言编写弹窗提示是否确认退出_世人觉得C语言和C++太难?没前途?过来人告诉你真相...
  2. mysql读书笔记---mysql safe update mode
  3. 在idea下开发出现404错误
  4. 深度好文 | 中间人攻击、ARP欺骗背后的原理及漏洞还原
  5. 菊子曰测试草稿{29C28FD771BA4B0D8693}
  6. java getSource()和 getActionCommand()区别
  7. Vue创建项目的详细步骤
  8. 艾客私域风暴进行时—打造服务型私域,赋能品牌增长新引擎
  9. Kubernetes部署策略:重建、滚动更新、蓝绿部署、金丝雀部署
  10. 快递鸟电子面单打印接口demo-可返回电子面单模板
  11. 屌丝经济”要突破的痛点在哪儿?
  12. mybatis学习与理解
  13. java支付宝对账功能开发_java后台实现支付宝对账功能
  14. jpa vue管理系统_如何通过利用Java流获取类型安全和直观的Hibernate / JPA查询
  15. 1--if中的return的作用/条件判断中如何退出函数
  16. 中科红旗开源Linux解决方案
  17. 卡尔曼滤波之目标跟踪
  18. Centos 7.2 及php7环境下升级memcache未果,改安装 memcached
  19. java练习 车费问题
  20. 百度搜索高级搜索指令和参数

热门文章

  1. R语言与非参数检验之单样本位置检验
  2. matlab mpt工具箱帮助文档_替代 Matlab 的国产软件出现?
  3. 适合 Kubernetes 初学者的一些实战练习(一)
  4. Angular 应用里的 vendor.js 是用来干什么的?
  5. Chrome 开发者工具无法显示服务器正常返回的 HTTP 请求 - Failed to load response data
  6. SAP Cloud for Customer(C4C)里如何定义跨BO间的association
  7. SAP Spartacus 数据类型定义汇总
  8. 通过单步调试理解Angular里routerLink指令实际url的生成逻辑
  9. 我ABAP开发生涯中搜集的一些有意思的数据库表
  10. 重新安装SCCM 2012 client,解决Windows10 1909在线更新问题