It's not a secret anymore!*
The moose likes Beginning Java and the fly likes Still Stacks Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Murach's Java Servlets and JSP this week in the Servlets forum!
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Still Stacks" Watch "Still Stacks" New topic
Author

Still Stacks

Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
I posted this awhile ago, but I didn't get a response. My stacks code finally worked but now instead of giving me "mine o Josie" when I type in "Josie o mine", I get "Josie o minemine o Josie".

Here's my code
Paul Sturrock
Bartender

Joined: Apr 14, 2004
Posts: 10336



and



Looks like you assign your user input to a String, then add more to that String. What it looks like you want to do is split (wonder if that word might be important...? ) your input at each space so you have an array of words. Then you can build a new String from this array by reading from the end of the array to the start.


JavaRanch FAQ HowToAskQuestionsOnJavaRanch
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Two issues...

I thought you used either tokenizer or split, not both.

Notice, the sentence does work, but it also repeats the original sentence as well.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Stephanie]: I thought you used either tokenizer or split, not both.

Yup. Nowadays many of us favor split(), but if you haven't learned about regular expressions yet, a tokenizer may be easier.

Notice, the sentence does work, but it also repeats the original sentence as well.

Peter quoted the line that's causing your trouble:

"phrase" is the same variable you're using to collect all your output, right? And here at the beginning, before reversing anything, you're assigning the whole line of text to the variable phrase. Which is why it's there as part of your output, unreversed.

It looks like your code has a number of sections that aren't really doing anything currently. Like maybe there are several past ideas which have been partially abandoned, but are still lying around in the code. For example, two out of three while loops have no effect at all on the output. You're only printing the "phrase" variable, so all the work done with the stack seems to be irrelevant. The result is that the code is considerably more complex and convoluted than it needs to be, which makes it harder for you to find a problem when one occurs. Try saving your current work to a backup file somewhere for reference, and then try commenting out some of the code that doesn't look like it does anything. If the output is not affected, then you can simply delete the code that was commented out. A shorter, simpler method will be easier for you to analyze. Some of this deleted code may represent ideas you may wish to return to later, which is why having a backup file is nice (actually, a good version control system is what you eventually want, but that's something to look into later I think).

Hope that helps...


"I'm not back." - Bill Harding, Twister
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Well, here's my problem. I need to do this using stacks. Can you help?
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
In that case, I think you should remove the calls to reverse() - in fact, take out the StringBuffers entirely. That represents an alternate solution which is independent of stacks. That will "break" your existing code, but no big deal. You previously posted a comparatively simple solution using a stack that worked pretty well, except that it was reversing by line rather than by word. See if you can take what you now know about StringTokenizer and see if you can use it to modify the earlier code to split up the input by words rather than (or in addition to) by lines.

To understand what is and is not working in your code, you might also benefit from putting in some more print statements, especially inside any loops. Use these to print out some of the intermediate results you get along the way, so you can tell whether the code is really doing what you think it is. It's hard to debug problems just by looking at the final answer. Eventually when you have the code working properly, you may want to remove or comment out most/all of these print statements. Eventually it would be good to learn how to do this with a logger of some sort (Log4J or the java.util.logging package, for example) but that's something to learn later, I think.

Good luck.
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Thanks Jim,

I still have issues with tokenizers. This is my second Java class and I seem to have trouble with the basics, and tokenizers weren't part of the first course. I'll take your last post and see if I can come up with something. I've been at this all day, so I need to get on with something else...that being looking for the software I got with my laptop so I can fix it...need that so "Josie o mine", my lab, won't bug me because I'm sitting at the desktop all day. My last lab, Jake, used to do the same thing so I bought a laptop and he seemed happier when I sat on the couch typing and he could lie next to me. Guess she has the same ideas.

If you would be so kind as to keep an eye out for my response to this subject, I would be most appreciative. My assignment is due tomorrow night, midnight EST...I'm mountain time.

Thanks so much for your time.

Steph
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
First, what is the requirement you're trying to meet? Are you reversing words or are you reversing the character order? Is it 1 or 2:

1. "Josie o mine" becomes "mine o Josie"
2. "Josie o mine" becomes "enim o eisoJ"

It's my impression you're trying to do 1 so that's what I'll answer. You already know everything you need to know to solve this, it looks like you're just too focused on doing it a certain way to see the simple way. Let's look at your code to start off.



Understand that a Stack is first-in-last-out (FILO) and as such the first Object you push to a stack will be the last Object you get from it. If you push five words to a stack in order they will come off the stack in reverse order. Consequently all you need to do is:

1. Get a sentence.
2. Push each word to the stack.
3. Pop each word off the stack and append it to a new sentence.
4. Print the new sentence.

You know how to get the sentence already by prompting the user. You know how to use a tokenizer to parse it into words. For each word you must push that word to the stack. When you're done, you can pop each word from the stack onto a new sentence using a StringBuffer or concatenation with +=. At that point it will be reversed so you can print it.

[code deleted - Jim]

[ November 28, 2005: Message edited by: Ken Blair ]
[ November 28, 2005: Message edited by: Jim Yingst ]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
For what it's worth, Ken, this thread is basically a continuation from here. That may provide some additional context for you.

Unfortunately I think your last bit of code came too close to giving the entire answer out. Since this is for a class assignment, I've deleted that last part from your post. Hope you understand.
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
It's the rest of the post that gives the answer away not the example. Ironic. I guess the problem is that the answer is actually so simple it's impossible to write code that doesn't give it away.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Well, toe-may-toe, toe-mah-toe I suppose. In fact I think all the parts of an answer have been floating around in code previously written by Stephanie already. At this point it's largely a matter of understanding what the parts are really doing, clearing away the cruft and focusing on the parts that matter.
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Ken and Jim,

My problem here is that the book says to push, top, and pop, but gives no examples of where to put them or how to write the code. My original code gave me an error message of "inconvertible types". My other file for this assignment has the pop() as void, but so is the push, which says "public void push(Object item)". I guess the (Object item) makes the difference. The top() says "public Object top()".

This is what my instructor responded when I sent her my code (she lives in Romania...).

1. The first while loop is useless. [So Ken has said.]
2. According to the specs, the sentence should be
reversed by using a stack not by the trivial call to
reverse method of class String. [Trivial???]
3. After reading the sentence in a String (which is ok
in your code) you should:
a. tokenize the string an[d] push the tokens onto the
stack (in a while loop);
b. in a loop (while the stack is not empty), take the
stack top item (followed by a pop), assemble a new
string and display it. Actually this is the reversed
sentence.

My problem with a and b is HOW!!!

Can you show me an example, or lead me to one, that doesn't give me the answer?

I mean, if pop() in my other file is void, how do I access it...or is what I have in my code correct?

I am so confused...This assignment is due tonight midnight EST. I've been working on it for days.

Steph
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Regarding using push() and pop() - you had code that was doing this correctly back here. The code posted November 25, 2005 02:51 PM was close to begin with. EFH's suggestion November 26, 2005 02:44 PM allowed you to fix the stack problem. By November 26, 2005 05:14 PM you had code that was reversing everything on a line-by-line basis. No StringBuffer or reverse() at this point, right? Great. The stack part is working perfectly here. Recreate this and save a copy for reference if you didn't already.

Now, how does this need to be modified? You've got code here that's reading each line and putting each line on the stack:

The variable says "word" but it's really a line at this point. So what you need to do here is, before calling stack.push(), insert some code that takes the current line (the thing currently called "word") and tokenizes it, breaking it up into words. You've done this sort of thing previously (from November 27, 2005 10:14 AM):

OK, that had the reverse() call too, but take that out:

You've got all the pieces here. It's really, really close to working. Don't lose faith.
[ November 29, 2005: Message edited by: Jim Yingst ]
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Now I get a runtime error saying "Push attempted on full stack"

Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
You're getting an exception with a stack trace, right? The exception has a stack trace with line numbers. If you look just at the line numbers that are within the ReverseSentence.java file, I bet the numbers point to this part:

It looks like you are pushing a bunch of numbers onto the stack. 0, 1, 2, 3... up to 199. What do these numbers have to do with reversing a sentence? And you're doing this inside a while loop, probably more than once. (Actually it's an infinite loop, it looks like, which is another problem.) So, the stack only holds 200 objects maximum, and that should probably be more than enough. But instead you're adding 200 numbers to the stack, and then another 200... So the stack breaks. But, there is no reason to add any numbers onto the stack at all. Certainly not 200 of them. You used to be putting Strings on the stack (like, either words or lines, which are the things you want to reverse). Pushing Strings was the right track.

Let's see - do you have a copy of code from right after you implemented EFH's suggestion? The code that was successfully reversing by line rather than by word? The code that I said in my last post "save a copy for reference"? Could you show what it looks like? Because that should be pretty close to what you need. You keep inventing new directions to go in after that, and I think you need to go back to that code that was close to working, before we lose track of it again.
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Ok. Here goes. I don't get errors, however...



This gets me "Josie o mine" from "Josie o mine"




This gets me "mine" from "Josie o mine"

Here's the whole code:

Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078


Your problem lies in the above code. You're trying to combine two different solutions it looks like. Tkae what you know from one and apply it to the other.



What does that do? It gets each word in a sentence. What does setting each word to the same variable do? It means each word will replace the previous one that used to be in that variable. But we just want to add each word to a stack, so why do we need to set it to a variable anyway? You have this while loop that gets each word already, if you want to add each word to a stack, then add each word to the stack in this while loop!



This has no place in your code. It's from a different solution. What is the difference between that solution and the one you need? It's that you need to add each wrod, not each line. Remove it because it's not necessary or useful, but apply what you know (how to add something to a stack) to the loop that was above it.

Your code should look, more or less, like this.



I could literally create a full working example by copy and pasting your existing code.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
OK Steph, your last couple posts doesn't seem to have anything to do with the instructions I had given in my last few posts, so to reduce confusion I am abandoning that effort since it seems doomed. Ken's got an alternate strategy to follow, which will also work, and I don't want to contradict that. Please, listen to what he's saying, and follow the hints.
Stephanie Dears
Ranch Hand

Joined: May 26, 2005
Posts: 43
Jim,

I'm sorry I am a rock when it comes to Java. I thought I did what you said...apparently not.

Unfortunately, I don't think I'll understand any better with Ken.

Ken,

I'm clear up to "Use tokenizer in while loop to get each word using nextToken()". If I'm correct, that includes:

StringTokenizer st = new StringTokenizer(phrase);
while (st.hasMoreTokens()){
word = st.nextToken();
word.trim();
} // end while

If I'm wrong about that, then...

After that, I'm clueless.

I thought "and push it to the stack" meant:



apparently not.

"Declare a new String for our backwards sentence.

Use a while loop to remove each word from the stack and append it to the string you just declared"

I have no clue how to do these last two things.


Jim and Ken,

I took an introductory course in Java. It touched on using methods from another file...and it seemed like it assumed we just knew how to do it. Our example was changing colors in a box...not moving words or manipulating other data. I didn't understand it then. I got the same responses to questions as I receive now.... It was the prerequisite to this course.

This class is no better (I intend to address this with my instructor tonight). Even here in the Java Ranch. While I appreciate that you folks don't want to give the answers when it comes to students, you assume we understand what you mean when you say "declare a new string for our backwards sentence." Or, "Use a while loop to remove each word from the stack and append it to the string you just declared."

Most frustrating is when you say "here is your code '....', that's your problem. And I fix it how?

While I understand what needs to be accomplished, I don't understand how it IS accomplished. Nobody explains HOW it is done.

Jim and Ken...I apologize for my venting, but I am truly frustrated. I DO appreciate your help...or attempts thereof.

Steph
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Steph - I had been trying to go back to before any StringBuffer or StringTokenizer had been brought in. At November 26, 2005 05:14 PM you said "I just tried it one word at a time and it reversed" - it sounded like you must have had the stack stuff working pretty well at that point, and if we could have used that as a known reference point for future improvements, that would have been cool. Everything I've seen since then was recombined in new and different ways, without successfully reversing anything the way your code once did (apparently). Ah, well...

To follow up from where you are now though...

[B][Steph]:

I'm clear up to "Use tokenizer in while loop to get each word using nextToken()". If I'm correct, that includes:
[/B]

Yes. This is getting each word using nextToken, one at a time. Now the thing to realize though is that every time we hit

the program basically forgets what the old value of word was, and remembers the new one instead. It can only remember one word at a time. When this loop is done, the varaible "word" refers to the last word from the line. So, if we want to do anything useful with the words that were previously obtained from the tokenizer (and yes, we do) then we need to do it before the loop ends. Specifically:



Specifically, we need to push each word onto the stack.

[B][Steph]: I thought "and push it to the stack" meant:


apparently not.[/B]

Well, the part we need is the part that says

The rest of the loop was reading lines from input - but we've already read words, in the preceding code. We don't want to read something else here; we want to use the word that was read in the previous code and put it in the stack.

I'm stopping there for now because previous attempts tried to do way too many different things one after another without understanding them - let's just see what we have so far.
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078

Ken,

I'm clear up to "Use tokenizer in while loop to get each word using nextToken()". If I'm correct, that includes:



If I'm wrong about that, then...


Tes, that's exactly what it includes. The trim() is unnecessary but it doesn't cause any harm either. The problem is now that you have a word, you don't do anything with it. This is the point where you need to push it on to the stack. As Jim said, add stack.push(word):




I thought "and push it to the stack" meant:



apparently not.


No. Pushing it to the stack means quite literally invoking stack.push(E) where "E" is whatever we are "pushing" on to the stack. Jim demonstrated this by pushing "word" to the top of the stack using stack.push(word) Think of a stack as a stack of papers. When you "push" a paper on to the top of the stack you are simply putting another page on it. When you "pop" something from the stack you are removing a page from the top. When you "peek" you are taking a peek at that page on the top but not removing it. Note that as far as I can tell with the particular stack implementation you are using "peek" is actually called top().

"Declare a new String for our backwards sentence.


Declare a new String:



That's it, a simple String declaration so that we can use it later.

Use a while loop to remove each word from the stack and append it to the string you just declared"


A while loop that removes each element (in our case each element is a word):



The question is, what do you do with that word? You'll be getting them in the reverse order you put them there, so why not just add them to a String as you get them? In fact... you could add them to that reverseSentence string we declared earlier using +=.
 
wood burning stoves
 
subject: Still Stacks
 
Similar Threads
Parsing of StringBuffer(URGENT)
Where did I go wrong?
Stacks
Palindrome
Stack ADT help