ZOJ-1004-Anagrams by Stack

来源:互联网 发布:用友js面试题 编辑:程序博客网 时间:2024/04/25 00:56

程序虽然Accpeted了,但是还是觉得有必要认真归纳一下解题过程,这样会比较有助于自己的提高,今天先从1004开始,其他题的日后再补上。

题目如下:

Anagrams by Stack


Time limit: 1 Seconds   Memory limit: 32768K  
Total Submit: 1583   Accepted Submit: 659  


How can anagrams result from sequences of stack operations? There are two sequences of stack operators which can convert TROT to TORT:

[

i i i i o o o o

i o i i o o i o

]

where i stands for Push and o stands for Pop. Your program should, given pairs of words produce sequences of stack operations which convert the first word to the second.

Input

The input will consist of several lines of input. The first line of each pair of input lines is to be considered as a source word (which does not include the end-of-line character). The second line (again, not including the end-of-line character) of each pair is a target word. The end of input is marked by end of file.

Output

For each input pair, your program should produce a sorted list of valid sequences of i and o which produce the target word from the source word. Each list should be delimited by

[

]

and the sequences should be printed in "dictionary order". Within each sequence, each i and o is followed by a single space and each sequence is terminated by a new line.

Process

A stack is a data storage and retrieval structure permitting two operations:

Push - to insert an item and
Pop - to retrieve the most recently pushed item

We will use the symbol i (in) for push and o (out) for pop operations for an initially empty stack of characters. Given an input word, some sequences of push and pop operations are valid in that every character of the word is both pushed and popped, and furthermore, no attempt is ever made to pop the empty stack. For example, if the word FOO is input, then the sequence:

i i o i o o

is valid, but

i i o

is not (it's too short), neither is

i i o o o i

(there's an illegal pop of an empty stack)

Valid sequences yield rearrangements of the letters in an input word. For example, the input word FOO and the sequence i i o i o o produce the anagram OOF. So also would the sequence i i i o o o. You are to write a program to input pairs of words and output all the valid sequences of i and o which will produce the second member of each pair from the first.

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

]

 

 

很明显这是一个要用到栈与回溯的题。

因为不想用STL,我最初设计了一个简单的栈类,存储源字符串,目标字符串和中间临时的字符串,后来想到由于临时字符串需要有记忆步骤的功能,于是为了练习C++的概念,添加了一个新类,让它继承前面简单的栈类,又附加了记录I/O步骤的功能以及相应的数据结构。记录I/O步骤是为了在遍历后找到和目标字符串对应的结果后,能直接输出所有步骤。

但是很遗憾,遍历并且筛选出合适组合的时间超出了我的想象,当输入为6个字符时,时间已经长达23秒,所以我点了Edit栏里的Select All,然后按下Backspace…..

 

因为懒得再重新写一遍栈类,所以还是用了STL,其实也只用到了pop()push()empty()top()4个成员函数,写一遍也花不了多长时间,以后还是自己写的好,多写多熟练思路也就开阔了。

 

下面这个最终Accpeted的程序结构非常清晰。在函数

void result(stack<char> &s)

中,用了3IF以实现递归回溯求解,这3IF的顺序很重要,判断是否输出结果在第一,另外输入判断if(sp<n)在输出判断if(!s.empty())前,既是思考上的顺序,同时也保证了题目中所要求的"dictionary order"

if(tp==n)
if(sp<n)
if(!s.empty())

对于swordtword字符数组,其实也可以用指针或栈来实现,不过我选择了用数组下标实现。其实栈说白了

是对数组及其下标的活用。

 

我在这道题的收获大概有两点:

1.  对于思路的考虑逻辑上一定要清晰严密,并且对于编程来讲具有可操作性。

2.  温习了栈与回溯的实现。

 

说到底,解所有题都是两个过程

1.  审题,得出解决问题的思路

2.  将大脑里的思路以程序代码的方式表达出来。

 

#include <iostream>
#include <string.h>
#include <stack>
using namespace std;
 
char sword[11];//来源字符串
char tword[11];//目标字符串
char step[100];//记录步骤的字符数组
int steplen,sp,tp,n;
//steplen:步骤长度
//sp:记录当前操作的字符在sword中的位置
//tp:记录当前操作的字符在tword中的位置
//n:被赋为字符串长度
 
 
void result(stack<char> &s)
{
    char ch;
    int i;
    if(tp==n)//与目标字符串校对完成,所以step必然是正确的
    {
        for(i=0;i<steplen;i++)
        {
            cout<<step[i]<<" ";        
        }
        cout<<endl;
        return;
    }
    
    if(sp<n)//对于源字符串挨个push进栈s产生输入i
    {
        s.push(sword[sp++]);
        step[steplen++]='i';        
        result(s);
        s.pop();
        steplen--;
        sp--;
    }
 
    if(!s.empty())//s不为空时,对比栈头和当前目标字符
    {              //如果相等,便产生输出o
        ch=s.top();
        if(ch==tword[tp])
        {
            s.pop();
            tp++;
            step[steplen++]='o';
            result(s);
            steplen--;
            tp--;
            s.push(ch);
        }
    }
}
 
int main()
{
    stack<char> strtemp;
    while(cin>>sword>>tword)
    {
        cout<<"["<<endl;
        n=strlen(sword);
        if(n==strlen(tword))
        {
            sp=0;tp=0;
            steplen=0;
            result(strtemp);
        }
        cout<<"]"<<endl;
    }
    return 0;
}

 

原创粉丝点击