问题大意
给予两个字符串a、b,需要将字符串a通过一系列出栈入栈操作使得最终出栈的字符串与b相同,并输出所有可实现方法的出入栈顺序。
输入
输入将包含几行输入。 每对输入行的第一行应视为源字(不包括行尾字符)。 每对的第二行(同样不包括行尾字符)是目标单词。 输入的结尾由文件结尾标记。
输出
对于每个输入对,需要产生一个有效序列的 i 和 o 的排序列表,这些序列从源单词产生目标单词。每个序列表都应以
[
]
分隔,并且序列应按照字典序排序,在每个 i 和 o 后面都有一个空格,并且每个序列以换行结尾
样例
Sample Input
madam
adamm
bahama
bahama
long
short
eric
rice
Sample Output
[
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 o i o i o o
]
解题思路
可通过深搜,将每一种可能序列遍历一遍,输出其中符合条件的序列。同时,可在递归中,优先判断入栈,可使得所得结果能按照字典序输出。
AC代码
#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<stack>
using namespace std;
stack<int>S;
char a[100005], b[100005];
char c[100005];
void dfs(int anow,int bnow,int clen) {
//anow 原字符串已经入栈了多少位 bnow 已出栈的已经符合目标字符串多少位 clen 解决方案已存储字符数量
if (clen == strlen(b) * 2) {
//由于每一次调用函数均会判断是否符合,故只要c种存了len个i,即len个o,就说明当前方案符合要求
for (int i = 0; i < clen; i++)
cout << c[i] << " ";
cout << endl;
}
//若原字符串未入栈完,则尝试入栈并调用函数
if (anow < strlen(a)) {
//入栈操作
S.push(a[anow]);
c[clen] = 'i';
//尝试入栈一位
dfs(anow + 1, bnow , clen + 1);
//将栈还原供后续操作
S.pop();
}
//若栈顶元素与目标字符串当前位置相同,则可尝试出栈
if (!S.empty() && S.top() == b[bnow]) {
//出栈操作
S.pop();
c[clen] = 'o';
//尝试出栈
dfs(anow, bnow + 1, clen + 1);
//还原
S.push(b[bnow]);
}
return;
}
int main() {
while (scanf("%s%s", a, b) != EOF) {
cout << "[" << endl;
dfs(0,0,0);
cout << "]" << endl;
}
}