zoj1004Anagrams by Stack

/*
题意:给出两个字符串A,B,栈的压入弹出操作使A变成B,i表示输入,o表示输出。
请求出所有可能的操作,按字典序输出。
分析:已知边界条件是压入次数==A.size()&&弹出次数==B.size()。用递归回溯求出所有可能的操作顺序
*/
#include<iostream>
#include<vector>
#include<string>
#include<stack>
#include<algorithm>
#include<cstring>
using namespace std;
string s1,s2;
stack <char> st;//存压入弹出的字母
vector <char> io;//存操作顺序
int l;
bool able(string a,string b)
{
	int num1[100],num2[100];
	memset(num1,0,sizeof(num1));
	memset(num2,0,sizeof(num2));
	if(a.size()!=b.size())return 0;
	for(int i=0;i<a.size();i++)
	    num1[a[i]-'a']++;
	for(int i=0;i<b.size();i++)
	    num2[b[i]-'a']++;
	for(int i=0;i<26;i++)
		if(num1[i]!=num2[i])return 0;
	return 1;
}
void DFS(int i,int o)//i表示压入的次数,o表示弹出次数
{
	if(i==l&&o==l)
	{
		for(int k=0;k<io.size();k++)
			cout<<io[k]<<" ";
		cout<<endl;
	}	
	if(i<l)//这步在前保证了字典序输出
	{
		st.push(s1[i]);
		io.push_back('i');
		DFS(i+1,o);
		io.pop_back();
		st.pop();
	}
	if(o<l&&o<i&&st.top()==s2[o])//可以弹出满足条件
	{
		st.pop();
		io.push_back('o');
		DFS(i,o+1);
		io.pop_back();
		st.push(s2[o]);
	}

}
int main()
{

   while(cin>>s1>>s2)
   {
	  
	   if(!able(s1,s2)){cout<<"["<<endl;cout<<"]"<<endl;continue;}
	   io.clear();
	   l=s1.size();
	   cout<<"["<<endl;
	   DFS(0,0);
	   cout<<"]"<<endl;
   }
}
原文地址:https://www.cnblogs.com/sook/p/2035221.html