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
]
输入
给定两个字符串,第一个字符串是源字符串,第二个字符是目标目标字符串。
输出
所有的进栈和出栈序列,输出结果需满足字典序。
【2018/11/16第二版代码】
#include <iostream>
#include <stack>
#include <string>
using namespace std;
stack <char> s1;
string a,b;
int l;
int in,out; //进栈。出栈次数
int num; //目前栈内元素个数
char ans[10001]; //存放答案
void dfs(int m);
int main()
{
while(cin>>a>>b) //多组测例
{
//cout<<a<<b;
int la=a.length();
int lb=b.length();
cout<<'['<<endl;
if(la==lb) //若两字符串长度相同才深搜
{
in=out=num=0;
l=la;
dfs(0);
}
cout<<']'<<endl;
}
return 0;
}
void dfs(int m) //m指代第m次操作
{
if(m==2*l) //操作数(出栈次数+入栈次数)应该等于两倍的字符串长度
{
while(!s1.empty()) //清空栈
{
s1.pop();
}
int j=0,k=0;
bool flag=true;
for(int i=0; i<m; i++)
{
if(ans[i]=='i') //入栈操作
{
char c=a[j++];
s1.push(c);
}
else //出栈操作
{
char d=s1.top();
if(d!=b[k++]) //若操作序列已不满足相等条件,那么跳出
{
flag=false;
break;
}
s1.pop();
}
}
if(flag) //若操作序列满足相等条件,输出一组答案
{
for(int i=0; i<m; i++)
{
cout<<ans[i];
if(i!=m-1) //结尾无空格
{
cout<<' ';
}
}
cout<<endl;
}
}
else
{
if(in<l) //入栈次数应<=字符串长度
{
ans[m]='i'; //第m次操作为入栈
in++; //入栈次数+1
num++; //栈内元素+1
dfs(m+1); //下一步操作
num--; //还原
in--;
}
if(out<l&&num>0) //出栈次数应<=字符串长度,且栈内元素个数必须>0
{
ans[m]='o';
out++;
num--;
dfs(m+1);
num++;
out--;
}
}
}
【2018/9/30第一版代码】:使用了tmp临时数组用来比较字符串a经操作后是否与字符串b相等
#include <iostream>
#include <stack>
#include <string.h>
using namespace std;
stack <char>s;
int length; //字符串长度
int in,out; //进栈/出栈次数
char start[1000]; //初始字符串
char target[1000]; //目标字符串
char tmp[1000]; //中间字符串
char step[2000]; //记录每一步的入栈/出栈操作
void dfs(int m);
bool ok(); //当前解能否符合要求
void output(); //输出一组解
int main()
{
while(cin>>start>>target)
{
int length1=strlen(start);
int length2=strlen(target);
in=out=0;
cout<<'['<<endl;
if(length1==length2)
{
length=length1;
dfs(0);
}
cout<<']'<<endl;
}
return 0;
}
void dfs(int m) //第m步操作,初始值为0
{
if(m==length*2)
{
if(ok())
{
output();
}
}
else
{
if(in<length)
{
in++;
step[m]='i';
dfs(m+1);
in--;
}
if(out<in)
{
out++;
step[m]='o';
dfs(m+1);
out--;
}
}
}
bool ok() //当前解能否符合要求
{
int i,j,k;
for(i=0,j=0,k=0; i<length*2; i++)
{
if(step[i]=='i')
{
s.push(start[j++]);
}
else
{
tmp[k++]=s.top();
s.pop();
}
}
for(int i=0; i<length; i++)
{
if(tmp[i]!=target[i])
{
return false;
}
}
return true;
}
void output() //输出一组解
{
int i;
for(i=0; i<length*2-1; i++)
{
cout<<step[i]<<' ';
}
cout<<step[i]<<endl;
}
【后记】
1.这道题好难啊……可能因为没有学过数据结构,对栈和C++都不太熟悉,还一昧的想着优化剪枝……昨晚写这个被虐到凌晨,今天下午午觉睡醒了重新做才做出来……
2.啊啊啊啊啊今晚超级坑爹的把源码覆盖掉了。。。亲眼看到源码在自己眼前消失的感觉。。。太难受了,还好在oj上找到了QAQ……一定要备份啊备份!魂淡!
3.重写第二次的时候发现,写的还没第一次好ORZ。。。。string和char*、string和string.h、size和sizeof和strlen…太复杂了吧!!!