1143.字母转换
时限:1000ms 内存限制:10000K 总时限:3000ms
描述
通过栈交换字母顺序。给定两个字符串,要求所有的进栈和出栈序列(i表示进栈,o表示出栈),使得字符串2在求得的进出栈序列的操作下,变成字符串1。输出结果需满足字典序。例如TROT 到 TORT:
[
i i i i o o o o
i o i i o o i o
]
输入
给定两个字符串,第一个字符串是源字符串,第二个字符是目标目标字符串。
输出
所有的进栈和出栈序列,输出结果需满足字典序
输入样例
madam adamm bahama bahama long short eric rice
输出样例
[
i i i i o o o i o o
i i i i o o o o i o
i i o i o i o i o o
i i o i o i o o i o
]
[
i o i i i o o i i o o o i
o i i i o o o i o i o i
o i o i o i i i o o o i
o i o i o i o i o i o i
]
[
]
[
i i o i
o i o o
]
先解释一下这个输入和输出,输出是先输出一个大括号,然后每行一种可能性的序列,不能输出就直接输出括号。
还有很重要的一点就是,由于输入是以空格为分开的标志,所以应该用scanf比较方便。
题目解析:表示这个题好难,,根本不会,看别人的代码看了半天才看懂,然后意识到原来做法这么简单,,,好了详细说一下这个题。因为是用回溯法做的,所以肯定会生成一棵子集树。就是代码中的search函数,可以看到从0到2*num的长度尝试了所有的0 1搭配,也就是所有的可能的出栈和入栈的顺序。然后把所有的0 1即出栈入栈存在rs数组里,其中0代表入栈,1代表出栈。此时我们可以想到,所有可能的搭配肯定是0 1个数相等的那些组合,因为将字符串出栈入栈转化成另一个字符串嘛,肯定出和入的次数要相等啊,还有一点可以想到的是:肯定先得有入栈才能有出栈即肯定先有0才能有1,不然空栈哪里来的栈顶元素来出,这都是很容易想到的。那么有了所有的出栈和入栈搭配之后,然后在test函数里面挨个检验,看那个出栈入栈的顺序得到的字符串跟目标字符串相同,那么就肯定是所求的答案之一(此时废话一句,这个答案肯定是现有0再有1而且肯定0 1的个数相同)。这个其实也用的是很经典的回溯法一般公式,即:
a[m]=0;
search(m+1);
a[m]=1;
search(m+1);
最后得到所有可能的结果,然后逐一检验。跟0 1背包问题,装载问题本质上都一样。废话不多说,代码如下:
#include<iostream>
#include<stack>
#include<stdio.h>
#include<string.h>
using namespace std;
char str1[100],str2[100];
int judge[100];
int len1,len2;
stack<char>s;
int test()
{
int i,j=0,k=0,flag=1,len=0;
char temp[100];
for(i=0;i<2*len1;i++)
{
len=len+judge[i];//首先,把当前树的序列号全部加起来
}
if(len!=len1)
{
flag=0;//如果不等于原字符串长度,就令flag等于0
}//因为可能的序列肯定是0 1的个数相等而且加起来等于字符串长度
for(i=0;i<2*len1;i++)
{
if(judge[i]==1)
{//对于当前枝干的每一个序列号,如果为1就从第一个字符开始把字符串入栈
s.push(str1[j]);
j++;
}
if(judge[i]==0)
{//如果哪一个为0,出栈
if(j>k)//入栈的肯定要比出栈的多
{
temp[k]=s.top();
s.pop();
k++;
}
else
{
flag = 0;
break;
}
}
}
for(k=0;k<len1;k++)
{
if(temp[k]!=str2[k])
{
flag = 0;
break;
}
}
return(flag);
}
void output()
{
int i ;
for(i=0;i<2*len1-1;i++)
{
if(judge[i]==1)
cout<<“i “;
else
cout<<“o “;
}
if(judge[2*len1] == 1)
cout<<“i”<<endl;
else
cout<<“o”<<endl;
}
void search(int m)
{//搜索函数的作用,生成一棵树,根据字符串的长度,生成二倍长的数有所有的组合
int i;
if(m==2*len1) //递归结束
{
if(test())//生成完之后进行test检验,若检验成功,就输出结果
output();
}
else
{
judge[m]=1;
search(m+1);
judge[m]=0;
search(m+1);
}
}
int main()
{
while(scanf(“%s”,str1) != EOF)
{
scanf(“%s”,str2);
len1=strlen(str1);
len2=strlen(str2);
while(!s.empty())//如果不是空,就清空栈
s.pop() ;
if(len1!=len2)//若两个字符串长度不相等,那么肯定不能匹配
cout<<“[“<<endl<<“]”<<endl;
else
{
cout<<“[“<<endl;//若相等,则搜索
search(0);
cout<<“]”<<endl;
}
}
return 0;
}