陈利人 面试题 给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。

原创 2013年12月06日 12:15:33

原题

  给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。例如s="abbbcb",t="abc",结果为3,即在s的所有子序列集合中,有3个子序列为t。

 

分析(老师的解法)

   给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。例如s="abbbc",t="abc",结果为3,即在s的所有子序列集合中,有3个子序列为t。 分析: 对于这个题目,我们可以很直观的想到递归解法,如果当前t[i]==s[j],则f[i,j] = f[i+1, j+1] + f[i, j+1],否则f[i,j] = f[i, j+1]。但是用递归的方法会产生大量的重复计算,时间复杂度很高。如何能减少重复计算呢,相信大家都能想到动态规划。仔细推敲一下是否能得到一个动态规划的递推公式。当t[i]==s[j]时,我们可以用当前的s[j]来匹配t[i],那么f[i,j]就依赖于f[i-1, j-1],同时,我们也可以不用当前的s[j]来匹配t[i],那么f[i,j]依赖于f[i,j-1],因此我们可以得到递推公式如下: if(t[i]==s[j]) f[i,j] = f[i-1][j-1] + f[i][j-1] else f[i,j] = f[i][j-1] 时间复杂度o(m*n),m和n分别是字符串s和t的长度。与这种题目类似的还有编辑距离问题,某个字符串是否是另外两个字符串的interleaving问题,这一类题目都是与字符串相关的动态规划问题,大家可以总结一下思路,下次遇到类似的相信很快就会得到解决方案

 

 

 

实验数据

 

 

 

 

代码

/*
*原题给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。
*求所有s的子序列集合中,有多少个子序列等于t。
*例如s="abbbc",t="abc",结果为3,即在s的所有子序列集合中,有3个子序列为t。
*/

#include<iostream>
#include<vector>
#include<string>
using namespace std;
int numSubSequence(string s,string t);

int main()
{
	string s = "abdbcbc",t = "abdc";
	cout<<numSubSequence(s,t)<<endl;
	system("pause");
	return 0;
}

int numSubSequence(string s,string t)
{
	if( s.size()==0 || t.size()==0 )
		return 0;
	vector< vector<int> > vec(t.size()+1);
	for(int i = 0; i <= t.size(); ++i)
	{
		vec[i].resize(s.size() + 1);
		vec[i][0] = 0;
	}
	for(int j = 0; j <= s.size(); ++j)
		vec[0][j] = 1;
	for(int i = 0; i < t.size(); ++i)
	{
		for(int j = 0; j < s.size(); ++j)
		{
			if(t[i] == s[j])
				vec[i+1][j+1] = vec[i][j] + vec[i+1][j];
			else
				vec[i+1][j+1] = vec[i+1][j];
		}
	}
	cout<<"   ";
	for(int j = 0; j < s.size(); ++j)
	{
		cout<<" "<<s[j];
	}
	cout<<endl;
	cout<<" ";
	for(int i = 0; i <= t.size(); ++i)
	{
		cout<<" ";
		for(int j = 0; j <= s.size(); ++j)
		{
			cout<<vec[i][j]<<" ";
		}
		cout<<endl;
		if(i < t.size())
			cout<<t[i];
	}
	
	return vec[t.size()][s.size()];
}


 

版权声明:欢迎查看本博客,希望对你有有所帮助

UVa 10340(子序列)

UVa 10340(子序列) 题目:子序列 题目描述: 输入两个字符串s和t,判断是否可以从t中删除0个或多个字符(其它字符顺序不变),得到字符串s. 例如:abcde可以得到bce,但无...
  • u010555622
  • u010555622
  • 2014年07月08日 02:38
  • 839

POJ 百炼 保研机试 2976:All in All

2976:All in All 查看提交统计提示提问 总时间限制: 1000ms 内存限制: 65536kB 描述给定两个字符串s和t,请判断s是否是t的子序列。...
  • u013240812
  • u013240812
  • 2015年10月31日 15:21
  • 830

C语言OJ项目参考(2290)字符串的修改

2290: 字符串的修改Description 一个字符串s、一个字符串t,判断t是否是s的子串,若是则将s中所有出现了t串的地方换成指定的字符或字符串p,若不是,则输出NO Input 一个字...
  • sxhelijian
  • sxhelijian
  • 2016年12月09日 19:02
  • 856

All in All

总时间限制: 1000ms 内存限制: 65536kB 描述给定两个字符串s和t,请判断s是否是t的子序列。即从t中删除一些字符,将剩余的字符连接起来,即可获得s。输入包括若干个测试数据。每个测...
  • believe__dream
  • believe__dream
  • 2015年01月05日 21:01
  • 386

C++之练习题23

1.给定两个由大小写字母和空格组成的字符串s1 和s2,它们的长度都不超过100 个字符、也可以长度为0。判断压缩掉空格、并忽略大小写后,这两个字符串在是否相等。...
  • fenger1943
  • fenger1943
  • 2014年07月28日 18:23
  • 573

陈利人 面试题 给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。

原题   给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。例如s="abbbcb",t="abc",结果为3,即在s的所有子...
  • cqs_2012
  • cqs_2012
  • 2013年12月07日 18:34
  • 1191

子串和子序列并不是一个意思

例如:一个字符串   awbcdewgh 他的子串:  awbc.   awbcd   awbcde   ....很多个子串  但是都是连续在一起   他的子序列: abc  .  abcd   ...
  • czkct
  • czkct
  • 2015年11月21日 13:10
  • 4306

网易内推笔试编程题-字符串子序列判断

题目描述: 牛牛拿到了一个藏宝图,顺着藏宝图的指示,牛牛发现了一个藏宝盒,藏宝盒上有一个机关,机关每次会显示两个字符串s和t,根据古老的传说,牛牛需要每次都回答t是否是s的子序列。注意,子序列不要求在...
  • SOLO_RAIN
  • SOLO_RAIN
  • 2016年08月03日 10:07
  • 1115

每天一道LeetCode-----计算字符串s中有多少个子序列和字符串t相等

Distinct Subsequences 原题链接Distinct Subsequences 判断字符串s中有多少个子序列和t相等,一个字符串的子序列是将字符串中若干字符删除后形成的字符串 ...
  • sinat_35261315
  • sinat_35261315
  • 2018年01月05日 21:19
  • 19

字符串子序列数目

出处:http://blog.csdn.net/sdjzping/article/details/13298343 1、http://acm.fzu.edu.cn/problem.php?pid...
  • isunn
  • isunn
  • 2015年04月18日 10:36
  • 1238
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:陈利人 面试题 给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。
举报原因:
原因补充:

(最多只允许输入30个字)