Saint Louis University |
Computer Science 180
|
Dept. of Math & Computer Science |
Topic: | Anagrams by Stack |
Source Code: | anagrams.cpp |
Live Archive Ref#: | variant of 2301 |
In-Class Day: |
Tuesday, 31 March 2009 |
Submission Deadline: | Friday, 3 April 2009, 11:59pm |
Techniques: |
Recursion |
Please review the general information about lab assignments.
In an earlier exam, we considered the use of a stack for reordering a set of objects from one permutation (e.g., abc) to another (e.g., bac) using the following rules. The characters are given with an initial order, and there is an intermediate stack that is initially empty. At each step, you may either take the next character from the initial order (if any) and push it onto the stack, or you may pop an item from the stack (if any), and place it as the next character in the output string.
As an example, we saw that if you start with the sequence abc
you can achieve the result bac by
pushing a, pushing b,
popping b,
popping a,
pushing c, and finally popping c.
We can describe this sequence of maneuvers as
More generally, some inputs may not have any valid conversions while
others may have more than one valid sequence.
For example, it is impossible to go from abc to cab,
intuitively because the only way to get c as the first output
character would be to do three pushes followed by a pop; yet at that
time, b is above a on the stack and must be
retrieved next.
Yet there are two ways to go from aab to aba, either
as
You are to develop a program that computes all possible sequences for converting one string to another using such rules.
Input: The first line will be a value 1 ≤ n ≤ 100 denoting the number of pairs to be considered. Following that will be n lines, each containing two strings. The first string designates the starting sequence and the second the goal configuration. The goal string will always be the same length as the starting string, and strings will have length at most 10.
Output: For each case, an initial line should announce the initial and goal strings, formatted as demonstrated below. Following that should be a line with the character [, followed by zero or more lines detailing the solutions, followed by a final line with the character ]. When there are multipel solutions, they should be presented in lexicographically sorted order, with the character + ordered before -.
Example input: | Example output: |
4 abc bac abc cab aab aba eeep epee |
Output for abc bac [ ++--+- ] Output for abc cab [ ] Output for aab aba [ ++-+-- +-++-- ] Output for eeep epee [ +++-+--- ++-++--- +-+++--- ] |
Use recursion to explore possible solutions to the problem. At any intermediate stage, there are two possible continuations (if legal). Try them both. We used the following signature:
/** Outputs, in sorted order, all solutions derivable from the given configuration */ void solve(const string& goal, // the goal string const string& I, // unused portion of "initial" string const string& S, // current stack sequence const string& O, // (partial) output string const string& moves // '++-+-' style trace of moves thus far ) {
We have intentionally chosen to use strings because they are conveninent to duplicate and manipulate ( C++ string documentation). We have also intentionally tagged them all as const in the signature so that you do not change their state within a single recursive call (but you may create different strings when invoking a further recursion).