25
Stacks and Queues Pepper

Stacks and Queues Pepper. Why History Simplicity Operating Systems – Function Call Stack

Embed Size (px)

Citation preview

Stacks and Queues

Pepper

Why

• History• Simplicity• Operating Systems– Function Call Stack

What is a Queue

• First In, First Out (FIFO)• Standard queue methods– add()– remove()– isEmpty()– peek()– size()

• Interface in Java – Can create as a LinkedList

What is a Stack

• Last In, First Out (LIFO)• Standard Stack Methods– push()– pop()– isEmpty()– peek()– size()

Creating and Adding Items

• Create both and add 5 itemsStack<String> st = new Stack<String>( );Queue<String> qu = new LinkedList<String>(); for (int c = 0; c < 5; c++) { qu.add(Integer.toString(c)); st.push(Integer.toString(c)); }

Iterating through every item

• Code to just run through until empty: while (!st.isEmpty()){ System.out.println(st.pop()); } while (!qu.isEmpty()){ System.out.println(qu.remove()); }

• Empties the structure though

Queue: Iterate through all & Recreate

• Queue: Just control by initial size and keep adding back

for (int c = 0; c < qu.size(); c++){ String value = qu.remove(); System.out.println(value); qu.add(value); }

• Removing values – Move the qu.size() call to before the loop because

the size will change.

Stack: Iterate through all & Recreate

• Stack: Cannot just push back because it will become your next value. Need auxillary structure.

Stack<String> temp = new Stack<String>();while (!st.isEmpty()){ String value = st.pop(); System.out.println(value); temp.push(value); }while (!temp.isEmpty()){ st.push(temp.pop()); }

Read Stack – if you only had a Queue

• Read through the stack and place on queue– Queue holds reverse order

• Place queue on stack – still reverse• Read through the stack and place on queue– Queue now holds original order

• Place queue on stack – original order

Compare two stacks using one temp

• Compare every item of Two stack contents• Leave stacks the same when done• When one has more items, it cannot be the

same• When you find a false result, cannot just

return false – have to put the items back• What order to put items back?• How do you get a true result?

Comparing stacks public static boolean isSameStack(Stack<String> st1, Stack<String> st2){ Stack<String> temp = new Stack<String>(); boolean res = true; if (st1.size() != st2.size()) { return false; } else {

while (!st1.isEmpty()){ String value1 = st1.pop(); String value2 = st2.pop(); temp.push(value1); temp.push(value2); if (!value1.equals(value2)){ // break and set value to false; res = false; break; } } // now put all the values back: while (!temp.isEmpty()){ st2.push(temp.pop()); st1.push(temp.pop()); } return res; // it will be true if nothing ever set it to false; } }

Splitting Tokens• To split an expression like (4 + (5 – 3))• Why not Scanner?• Making your own splitter– Holds• Queue of characters• Next entry waiting• Special characters we are searching for

– Methods• peek• hasNext• next

Loading the Character Queue

public StringSplitter(String str){ ch = new LinkedList<Character>(); for (int c = 0; c < str.length(); c++){ ch.add(str.charAt(c)); } findNextToken(); }

How to find the next token

• Skip whitespace• If the queue is empty, set the token to null• Pull out one character– If it is a special character, you are done– If it is a number, keep going until you get

whitespace or a special character

Finding the Token public String findNextToken(){ this.token = ""; // skip any whitespace while (!ch.isEmpty() && Character.isWhitespace(ch.peek())){ ch.remove(); // just throw away the whitespace } // now we are past the whitespace. Continue until end or special char //if the next one is empty there is no token if (ch.isEmpty()) { token = null; } else // something in token {

Finding the token part 2 token = "" + ch.remove(); //was it a special character or number if (!SPECIAL_CHAR.contains(token)){ // keep going until end of number skipping white space, // ending at number's end boolean done = false; while (!ch.isEmpty() && !done){ char nextone = ch.peek(); if (Character.isWhitespace(nextone) || SPECIAL_CHAR.contains("" + nextone)) { done = true;} else { token = token + ch.remove(); } } } }

return token; }

Next • The token is already waiting for you, so give it

and determine the next token.

public String next(){ if (token == null) { throw new

NoSuchElementException(); } String nextToken = token; findNextToken(); // reset the token return nextToken; }

Simple testpublic class StringSplitterTester{ public static void main (String[] args) { StringSplitter ss = new StringSplitter( "18.4-((2.3*8.5 ) / (19.5 + (2.7 ^ 4.9 ))))"); while(ss.hasNext()){ System.out.println(ss.next()); } }}

Evaluating the Expression

• Dijkstra's method• Push all symbols on one stack• All numbers on the other stack• When you reach a ), evaluate 2 numbers and

their one operation• Push that result back onto the stack

Expression – Create the ADTs

Stack<String> symbols = new Stack<String>(); Stack<Integer> numbers = new Stack<Integer>(); StringSplitter ss = new StringSplitter(expression); boolean bad = false;

Evaluate Expression - body while(ss.hasNext()){ String token = ss.next(); if (token.equals(")")) { // process the expression } else if (StringSplitter.SPECIAL_CHAR.contains(token)) { symbols.push(token); } else { numbers.push(Integer.parseInt(token)); } } if (bad) { System.out.println("The answer is - no answer"); } else { System.out.println("The answer is " + numbers.pop()); } } }

Calculating 2 operandsString operation = symbols.pop();

Integer firstNum = numbers.pop(); Integer nextNum = numbers.pop(); String openparen = symbols.pop(); if (openparen.equals("(")) { if (operation.equals("+")){ numbers.push(firstNum + nextNum); } else if (operation.equals("-")) { numbers.push( nextNum - firstNum); } else { bad = true; } } else { bad = true; }

HTML Splitter

• Split by < and > instead of (*,etc• Toss anything not inside < > • Need to identify the starter and ender

characters: – <– >

HTML Processor

• Read through the queue pushing onto the stack whenever a token must be matched. – When you encounter a / at the end, it means it is

a self closing tag, so don't push it onto the stack

• When you encounter a / at the beginning, it is supposed to close something that is right before it. – Pop the last item, it should have matching first

words of the tag.

Stacks and Queues

• What• Why• Patterns:– Read and restore• Queues just keep moving onto itself• Stacks require an auxillary storage

– Compare