在此保存下近段时间做的DP在字符匹配上的实现的题目

对于不同的字符串来说,2者只能不断将下标往后推移来实现匹配从而得到的最大匹配数

如 abcd 和 dcba 这个最大匹配数只能为1,因为两个d匹配后,在第一个字符串中是不能再拿前面的字符进行匹配的(当然你要是匹配a,b,c也是一样的道理)

对于每一道题目若想不断找到那个匹配成功的字符的话,我们需要一个函数不断递归找到前一个匹配成功的字符,这里引进一个T[N][N]的标志位来帮助我们判断何时进行递归

这里的题都是有关这个的形式

1.POJ 1458http://vjudge.net/problem/viewProblem.action?id=17083

这就是最基本的2个字符串的最大匹配数

dp[i][j]代表前一个字符串取i位,后一个字符串取j位时得到的最大匹配数

DP 方程:dp[i][j]={dp[i-1][j-1]+1,a[i]==b[j] | max(dp[i-1][j],dp[i][j-1])}

自己一开始在做题时写成了dp[i][j]={dp[i-1][j-1]+1,a[i]==b[j] | max(dp[i][j],dp[i-1][j-1])}

这样仔细想想很容易发现dp[i][j]=max(dp[i][j],dp[i-1][j-1]) 只是考虑了一部分的状态,而且本身在i,j2次循环时dp[i][j]也只出现了一次,也就是说只

进行了一次赋值操作,根本就不会进行更新操作

dp[i][j]=max(dp[i-1][j],dp[i][j-1])却可以在循环中不断将前面得到的最大值赋给后面;

for(int j=1;j<=lb;j++)
                if(a[i-1]==b[j-1])
                {
                    dp[i][j]=max(dp[i][j],dp[i-1][j-1]+1);
                }
                else dp[i][j]=max(dp[i][j-1],dp[i-1][j]);//这一段要注意,这是为了匹配到2段数组均在小于它的情况下所得
        }
总代码如下:

#include <cstdio>
#include <cstring>
using namespace std;
#define N 1001
#define max(a,b) a>b?a:b;
int dp[N][N];
char a[N],b[N]; int main()
{
while(scanf("%s%s",a,b)!=EOF){
memset(dp,,sizeof(dp));
int la=strlen(a),lb=strlen(b);
for(int i=;i<=la;i++){
for(int j=;j<=lb;j++)
if(a[i-]==b[j-])
{
dp[i][j]=max(dp[i][j],dp[i-][j-]+);
}
else dp[i][j]=max(dp[i][j-],dp[i-][j]);//这一段要注意,这是为了匹配到2段数组均在小于它的情况下所得
}
printf("%d\n",dp[la][lb]);
}
return ;
}

但是我们想要不断找到那个匹配成功的字符的话,我们需要一个函数不断递归找到前一个匹配成功的字符,这里引进一个T[N][N]的标志位来帮助我们判断何时进行递归

这是递归函数

 void output(int len1,int len2)
{
if(len1==||len2==) return;
if(T[len1][len2]==){
output(len1-,len2-);
printf("%c\n",a[len1-]);
}
else if(T[len1][len2]==) output(len1-,len2);
else output(len1,len2-);
}

这是T[][]在进行寻找最长子序列时进行赋值

在第二题中要用到这个方法,就不再详述

2.POJ 2250

http://vjudge.net/problem/viewProblem.action?id=17325

这与上面不同的是这是给2堆字符串,找其中尽可能多的相同的字符串并输出

这里需要用到output(int,int)进行递归调用

总代码如下:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
using namespace std;
#define N 103
string a[N],b[N];
int dp[N][N],T[N][N],len1,len2,cnt=; void match(int len1,int len2)
{
memset(dp,,sizeof(dp));
for(int i=;i<=len1;i++)
{
for(int j=;j<=len2;j++)
{
if(a[i-]==b[j-]) dp[i][j]=dp[i-][j-]+,T[i][j]=;
else{
if(dp[i-][j]>dp[i][j-]) dp[i][j]=dp[i-][j],T[i][j]=;
else dp[i][j]=dp[i][j-],T[i][j]=;
}
}
}
}
void output(int m,int n)
{
if(m==||n==) return;
if(T[m][n]==){
output(m-,n-);
cnt++;
if(cnt==dp[len1][len2])
cout<<a[m-]<<endl;
else cout<<a[m-]<<' ';
}
else if(T[m][n]==) output(m-,n);
else output(m,n-);
}
int main()
{
string str;
while(cin>>str)
{
len1=,len2=;
a[]=str;
while(cin>>str&&str.at()!='#'){
a[len1++]=str;
}
while(cin>>str&&str.at()!='#'){
b[len2++]=str;
}
match(len1,len2);
output(len1,len2);
//cout<<dp[len1][len2]<<endl;
}
return ;
}

DP在字符匹配上的实现的更多相关文章

  1. 《LeetBook》leetcode题解(10): Regular Expression Matching——DP解决正则匹配

    我现在在做一个叫<leetbook>的免费开源书项目,力求提供最易懂的中文思路,目前把解题思路都同步更新到gitbook上了,需要的同学可以去看看 书的地址:https://hk029.g ...

  2. 【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...

    37.(字符串)有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环, ...

  3. (转)MySQL数据表中带LIKE的字符匹配查询

    MySQL数据表中带LIKE的字符匹配查询 2014年07月15日09:56    百科369 MySQL数据表中带LIKE的字符匹配查询 LIKE关键字可以匹配字符串是否相等. 如果字段的值与指定的 ...

  4. leetcode 44 字符匹配

    题意:s是空串或包含a-z字母: p为包含a-z字母或?或 * (其中*可以匹配任意字符串包括空串,?可以匹配任意字符). 思路: 1)特殊情况:当s为空串时,p为连续 * 时,则连续 * 的位置都为 ...

  5. 请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

    // test20.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> #include< ...

  6. KMP算法——字符匹配

     暴力匹配: 假设现在我们面临这样一个问题:有一个文本串S,和一个模式串P,现在要查找P在S中的位置,怎么查找呢? 如果用暴力匹配的思路,并假设现在文本串S匹配到 i 位置,模式串P匹配到 j 位置, ...

  7. Python 基础之正则之一 单字符,多字符匹配及开头结尾匹配

    一.正则表达式之单个字符匹配 格式:lst = re.findall(正则表达式,要匹配的字符串)预定义字符集 匹配内容 .匹配任意字符,除了换行符\n \d匹配数字 \D匹配非数字 \w匹配字母或数 ...

  8. Java 字符终端上获取输入三种方式

    http://blog.csdn.net/hongweigg/article/details/14448731 在Java 字符终端上获取输入有三种方式: 1.java.lang.System.in ...

  9. JavaScript正则表达式模式匹配(1)——基本字符匹配

    var pattern=/g..gle/; //点符号表示匹配除了换行符外的任意字符 var str='g78gle'; alert(pattern.test(str)); var pattern=/ ...

随机推荐

  1. 生成HTML表格的后台模板代码

    有时候,我们需要在后台拼接生成前端的html表格,一般的做法就是各种string.StringBuilder的拼接(例子省略...),这样的话如果表头不同就没法做到代码的重用,增加代码的冗余,下面我分 ...

  2. P1851 好朋友

    题目背景 小可可和所有其他同学的手腕上都戴有一个射频识别序列号码牌,这样老师就可以方便的计算出他们的人数.很多同学都有一个“好朋友” .如果 A 的序列号的约数之和恰好等于B 的序列号,那么 A的好朋 ...

  3. Ubuntu rar的坑

    通过apt-get安装rar后,执行rar命令会有如下坑: rar: loadlocale.c:130: _nl_intern_locale_data: Assertion `cnt < (si ...

  4. intellij idea 调试 lua程序, 突然崩溃或者xmx不够的情况

    将内存各方面的数值都改大一点.都什么时代了,默认数值还这么低... -server-Xms256m-Xmx1024m-XX:ReservedCodeCacheSize=240m-XX:+UseConc ...

  5. WEB前端学习有用的书籍

    WEB前端研发工程师,在国内算是一个朝阳职业,这个领域没有学校的正规教育,大多数人都是靠自己自学成才.本文主要介绍自己从事web开发以来(从大二至今)看过的书籍和自己的成长过程,目的是给想了解Java ...

  6. Ant题解

    Description: 一根长度为L厘米的木棒上有N只蚂蚁,每只蚂蚁要么向左走,要么向右走,速度为1厘米/秒.当两只蚂蚁相撞时,他们会同时掉头(掉头时间不计)给出每只蚂蚁距离木棒左端的距离,问多少秒 ...

  7. RxJava的map方法与flatMap方法

    简单讲,map和flatMap都是来完成Observable构造的数据到Observer接收数据的一个转换,这么说有点绕

  8. JavaScript 声明全局变量与局部变量

    一.JavaScript 声明全局变量的三种方式: 声明方式一: 使用var(关键字)+变量名(标识符)的方式在function外部声明,即为全局变量,否则在function声明的是局部变量.该方式即 ...

  9. 洛谷 P1832 A+B Problem(再升级)

    题目背景 ·题目名称是吸引你点进来的 ·实际上该题还是很水的 题目描述 ·1+1=? 显然是2 ·a+b=? 1001回看不谢 ·哥德巴赫猜想 似乎已呈泛滥趋势 ·以上纯属个人吐槽 ·给定一个正整数n ...

  10. 【整理】用JSON-server模拟REST API

    用JSON-server模拟REST API https://www.cnblogs.com/ys-wuhan/p/6387791.html