问题描述:
通过栈交换字母顺序。给定两个字符串,要求所有的进栈和出栈序列(i表示进栈,o表示出栈),使得字符串2在求得的进出栈序列的操作下,变成字符串1。输出结果需满足字典序。例如TROT 到 TORT:
[
i i i i o o o o
i o i i o o i o
]
输入
给定两个字符串,第一个字符串是源字符串,第二个字符是目标目标字符串。
输出
所有的进栈和出栈序列,输出结果需满足字典序
分析:对于一次转换,进栈出栈的次数无法确定,可用一个较大数组来保存进战出战的情况。对于每一步,有可能出,也有可能进。可以一边穷举一边检验,直到结果出来。但是无限穷举是不可能的,根据问题,可加上适当的剪枝条件。显然,可使用回溯算法,搜索子集树,并添加限界条件。
伪代码:
若 result==目标&&栈为空&&无子母可以进栈
查找成功
打印
进栈:
若 有字母可进入
{
进栈
搜索下一个
出栈 //恢复状态
}
出栈:
若 有字母可出
获取出栈后的输出结果result1
若result1是result的从下标0开始的子串
出栈
搜索下一个
进栈 //恢复状态
源代码:(请根据自己的需要修改输出格式!)
//
// main.cpp
// 字母转换
//
// Created by dong on 15/9/13.
// Copyright (c) 2015年 dong. All rights reserved.
//
#include <iostream>
#include <stack>
using namespace std;
char A[10000];
string s,dest;
string result="";
stack<char> trans;
bool success=false;
void print(int i){
cout<<"[";
for(int k=0;k<i;k++)
cout<<A[k];
cout<<"]";
}
bool isSubstrofDest(string s){
int len=(int)s.length();
return s==dest.substr(0,len);
}
void run(int i,int j,string result){
if(result==dest&&trans.empty()&&j==s.length())
{
success=true;
// cout<<result<<endl;
print(i);
// exit(0);
}
if(j<s.length()){
A[i]='i';
trans.push(s[j]);
run(i+1,j+1,result);
trans.pop();
}
if(!trans.empty()){
string result1=result;
char top=trans.top();
result1.append(1,top);
if(isSubstrofDest(result1)){
A[i]='o';
trans.pop();
run(i+1,j,result1);
trans.push(top);
}
}
}
int main(int argc, const char * argv[]) {
cin>>s>>dest;
run(0,0,result);
if(!success)
cout<<"[]"<<endl;
return 0;
}