原题
给定两个字符串s和t(len(s)>len(t)),t可能是s的一个子序列。求所有s的子序列集合中,有多少个子序列等于t。例如s="abbbcb",t="abc",结果为3,即在s的所有子序列集合中,有3个子序列为t。
分析(自己的解法)
拿例子说吧我自己建树,这个树在程序里是虚拟的。不过可以帮助我们更好的理解并解决问题。请看下面
s="abbbcb",t="abc"
我们首先拿t的第一个字符去在s中匹配,匹配所有的
这时候我们s中的第一个就匹配成功,然后以它作为根,建“树”,
接着我们会拿t中的第二个去在s刚才那个字符之后的区间里去匹配,然后匹配成功的作为刚才那个字符的孩子,接着依次类推t中的所有的字符去匹配s中的特定区间。。。。
最后我们得到一个森林,也可能是一棵树。
然后我们找到所有叶子为t中最后一个字符的总的数目,即为答案所求。
原理:每一条从根a到叶子c的路径上的字符顺序组成的字符串都是t的子串,真子串不是我们想要的。例如路径"ad"不是我们想要的,“adc”本身才是我们想要的,所以只要值域为t最后一个字符的叶子,它的数目即为答案。
实验数据
代码
#include<iostream>
#include<string>
using namespace std;
void getString(string &s,string &t);
void MakeTree(const string &s,size_t n,const string &t,size_t m);
int result = 0;
int main()
{
string s;
string t;
getString(s,t);
MakeTree(s,0,t,0);
cout<<result<<endl;
system("pause");
return 0;
}
void getString(string &s,string &t)
{
cout<<"please input string s and t"<<endl;
cin>>s;
cin>>t;
}
void MakeTree(const string &s,size_t n,const string &t,size_t m)
{
if( n < s.size() && m < s.size())
for(size_t i = n; i < s.size(); i++)
{
if(s.at(i) == t.at(m))
{
if((m + 1) == t.size())
++result;
else
MakeTree(s, i + 1, t, m + 1);
}
}
}