I'm writing a program that asks the user for a postfix expression, and then outputs the result to the expression. I am attempting to do this using a Singly Linked List, and using the Adapter Pattern to create a stack.
The code for the SinglyLinkedList class, the LinkedStack class, and the Stack implementation are all straight out of a Data Structures book that I own. So the SinglyLinkedListTest class is the only one that has my own code in it (and has errors).
I've written a program that simply uses a stack to evaluate a postfix expression before, but I'm getting confused this time with the extra classes included.
I'm sure I have a ton of errors, but the most obvious ones to me are in my SinglyLinkedListTest class, every time I push a value onto the stack. I know the issue is that I am attempting to push Objects and characters onto the stack instead of the arguments that match push(E e), but I don't know how to alter my code to make this work.
Any suggestions or input would be greatly appreciated.
Here is my Stack Implementation:
package PostFix;
public interface Stack<E>
{
int size();
boolean isEmpty();
void push(E e);
E pop();
}
Here is my LinkedStack class:
package PostFix;
public class LinkedStack <E> implements Stack<E>
{
private SinglyLinkedList<E> list = new SinglyLinkedList<>();
public LinkedStack()
{
}
public int size()
{
return list.size();
}
public boolean isEmpty()
{
return list.isEmpty();
}
public void push(E e)
{
list.addFirst(e);
}
public E pop()
{
return list.removeFirst();
}
}
Here is my SinglyLinkedList class:
package PostFix;
public class SinglyLinkedList<E>
{
private static class Node<E>
{
private E element;
private Node<E> next;
public Node(E e, Node<E> n)
{
element = e;
next = n;
}
public E getElement()
{
return element;
}
public Node<E> getNext()
{
return next;
}
}
private Node<E> head = null;
private Node<E> tail = null;
private int size = 0;
public SinglyLinkedList()
{
}
public int size()
{
return size;
}
public boolean isEmpty()
{
return size == 0;
}
public void addFirst(E e)
{
head = new Node<>(e, head);
if (size == 0)
{
tail = head;
}
size++;
}
public E removeFirst()
{
if (isEmpty())
{
return null;
}
E answer = head.getElement();
head = head.getNext();
size--;
if (size == 0)
{
tail = null;
}
return answer;
}
}
Here is my final SinglyLinkedListTest class:
package PostFix;
import java.util.Scanner;
public class SinglyLinkedListTest
{
public static void main(String[] args)
{
Double num1, num2, answer;
char c;
Stack<Double> stack = new LinkedStack<>();
Scanner input = new Scanner(System.in);
System.out.println("Enter the expression you would like to evaluate: ");
String someString = input.nextLine();
for (int index = 0; index < someString.length(); index++)
{
c = someString.charAt(index);
if (Character.isDigit(c))
{
stack.push((double)Character.digit(c, 10));
}
else if (c == '+')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1+num2;
stack.push(answer);
}
else if (c == '-')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1-num2;
stack.push(answer);
}
else if (c == '*')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1*num2;
stack.push(answer);
}
else if (c == '/')
{
num2 = stack.pop();
num1 = stack.pop();
answer = num1/num2;
stack.push(answer);
}
}
System.out.println("The result is: " + stack.pop());
}
}
Stack<String> buffer = new LinkedStack<>();
Poor name: call it stack.
You've declared it as Stack<String> but you're pushing chars:
buffer.push(someString.charAt(index));
and Objects:
buffer.push(answer);
and popping ints:
num1 = buffer.pop();
You are never either pushing or popping strings.
Just make up your mind. You should be pushing and popping ints, or longs, or doubles, or BigDecimals, depending on what precision you need.
EDIT
buffer.push((double)c);
is invalid. You're pushing the ASCII value, not the numeric value it corresponds to. You need
buffer.push((double)Character.digit(c, 10));
You also need an else after each if block: if the character is a digit, it won't be a +, and if it's a + it won't be a -, etc.
Related
I'm trying to implement an inorder, preorder, and postorder traversal algorithm for my BST. It seems that the inorder algorithm is working so far, but it's only returning the first character of the word. I realize that I'm returning char c, but I'm confused on how I would make it return the entire word. Any help would be highly appreciated!
package main;
import java.io.*;
import java.util.*;
// Node class
class Node
{
char c;
boolean end;
Node left, right;
public Node(char c)
{
this.c = c;
this.end = false;
this.left = null;
this.right = null;
}
}
class BinarySearchTree
{
private Node root;
public BinarySearchTree()
{
root = null;
}
public void addValue(String s)
{
root = addValue(root, s, 0);
}
private Node addValue(Node x, String s, int d)
{
char c = s.charAt(d);
if (x == null)
x = new Node(c);
if (c < x.c)
x.left = addValue(x.left, s, d);
else if (c > x.c)
x.right = addValue(x.right, s, d);
else x.end = true;
return x;
}
public boolean search(String s)
{
return search(root, s, 0);
}
private boolean search(Node x, String s, int d)
{
if (x == null)
return false;
char c = s.charAt(d);
if (c < x.c)
return search(x.left, s, d);
else if (c > x.c)
return search(x.right, s, d);
else
return x.end;
}
public void inorder(){
inorder(root);
}
private void inorder(Node r){
if (r != null){
inorder(r.left);
System.out.print(r.c);
inorder(r.right);
}
}
}
public class Project2
{
public static void main(String[] args) throws Exception
{
BinarySearchTree tree = new BinarySearchTree(); // Make new BST object
// Variable for scanned word
String token = "";
// Use scanner for input file
Scanner scan = new Scanner(new File("10words.txt")).useDelimiter("\\s+");
//Check for next line in text file
while (scan.hasNext())
{
token = scan.next();
tree.addValue(token);
}
scan.close();
tree.inorder();
Scanner inputWord = new Scanner(System.in);
System.out.print("\nEnter a word to search: ");
String word = inputWord.next().toLowerCase();
if(tree.search(word) == false){
System.out.println("Word NOT Found!");
} else{
System.out.println("Word Found!");
}
inputWord.close();
}
}
I did not look at your inorder code but you said it works so I'll believe you.
However I did take a look at your addValue code and you only save the first character here. No wonder you can't get the entire word back, you just don't save it :P
Instead, you should change your Node class to accept a String instead of a character. You won't need the d parameter in your addValue method then either.
The Java String class provides the .compareTo () method in order to lexicographically compare Strings. You can use it with string.compareTo(otherString)
This method will return a value < 0, equal to 0 or > 0.
< 0 means string is lexicographically smaller than otherString (for example: "Apple" would be smaller than "Banana")
= 0 means it's the exact same word
> 0 means string is bigger than otherString (for example: "Banana" would be bigger than "Apple")
your addValue method looks like it is incorrect. it only modifies the root, then character will be equal, so it returns. In particular d is never modified.
On a more fondamental level, a BST would be appropriate to look for a character in a tree, not for looking for a String. If you want to look for a word, you can use a Trie instead (which is not a binary tree).
I'm having trouble with programming a function in Java.
First i have implemented a Stack through a Single Linked List, like this:
public class ListStack<E> implements Stack<E> {
private static class Node<T> {
private T item;
private Node<T> next;
private Node(T item, Node<T> next) {
this.item = item;
this.next = next;
}
}
private Node<E> first;
private int size;
public ListStack() {
this.size = 0;
this.first = null;
}
#Override
public E peek() {
return first.item;
}
#Override
public void pop() {
first = first.next;
size--;
}
#Override
public void push(E e) {
Node<E> node = new Node<E>(e, first);
first = node;
size++;
}
#Override
public boolean isEmpty() {
return (first == null);
}
#Override
public int size() {
return size;
}
#Override
public Stack<E> reverse(){
ListStack<E> reversed = new ListStack<E>();
Node<E> node = first;
while(node != null){
reversed.push(node.item);
node = node.next;
}
return reversed;
}
}
Then i have created a stackof a type X. Here's that type's definition and constructor:
private String first, second;
private ListStack<String> text;
public X(String first, String second){
this.first = first;
this.second = second;
this.text = new ListStack<String>();
}
There are getters for both the strings firstand second, getFirst(), and getSecond(), respectively.
Then i want to write a function that basically, for each X of the stack, checks if the String second is equal to the String txt, passed as the function's argument. If it is, it returns X and deletes the Node from the stack, otherwise just returns null.
Here's my implementation of the method:
First, as a private attribute of the class:
private Stack<X> text; //for simplicity, let's assume the stack already contains values of type `X`.
Then:
private X getX(String txt) {
Stack<X> stack = text.reverse();
Stack<X> stack_final = new ListStack<X>();
X c;
String txt2;
boolean found = false;
for (int i = 0; i < stack.size() && !found; i++) {
c = stack.peek(); //extracts the element
txt2 = c.getSecond(); //gets the name
if (txt2.equals(txt)) {
found = true;
stack.pop();
} else
stack_final.push(c);
stack.pop();
}
if (found) {
text = stack_final;
return c;
}
else
return null;
}
What am i doing wrong ?
My guess is that i'm not updating the final stack correctly, with only the values that don't check, but i'm not sure it is that...
The main problem is the for-loop. Just step through it in your head:
i=0 stack=[1,2,3,4,5,6] stack_size=6
i=1 stack=[2,3,4,5,6] stack_size=5
i=2 stack=[3,4,5,6] stack_size=4
i=3 stack=[4,5,6] stack_size=3
the code actually breaks off after reading only half of the stack. You should rather use isEmpty() than a counter.
private X getX(String txt){
Stack<X> stack = text.reverse();
Stack<X> stack_final = new ListStack<X>();
X c = null;
while(!stack.isEmpty()){//transfer all items from stack to stack_final
//retrive and remove the first item from stack
X x = stack.peek();
stack.pop();
if(x.getSecond().equals(txt))//save x as searched item, if it matches
c = x;
//add the item to stack_final
stack_final.push(x);
}
//save stack_final as text (stack_final is a copy of text)
text = stack_final;
//c is either the searched item, or null, if no item was found
return c;
}
And btw., it's common that pop() returns the removed element.
public X pop(){
X res = first.item;
first = first.next;
return res;
}
You will get a NullPointerException if you try to peek() or pop() an empty stack!
public E peek() {
return first.item; // first is null if stack is empty!
}
public void pop() {
first = first.next; // first is null if stack is empty!
size--;
}
The Java Stack class throws an EmptyStackException in those cases.
Then I want to write a function that basically, for each X of the stack, checks if the String second is equal to the String txt, passed as the function's argument. If it is, it returns X and deletes the Node from the stack, otherwise just returns null.
Now, to achieve what you asked, you can simply do:
Stack<X> stack = text.reversed();
X elementFound = null;
while (!stack.isEmpty()) {
if (txt.equals(stack.peek().getSecond()) {
elementFound = stack.peek();
} else {
stackCopy.push(stack.peek());
}
stack.pop();
}
// now stack is empty and stackCopy contains stack reversed and without
// elementFound, if elementFound is not null (meaning it was found)
text = stackCopy; // stack was text reversed
return elementFound;
public class AdjList {
private Node first; // beginning of list
private int N; // size of lis
private static class Node {
int a;
Node next;
Node(int a, Node next) {
this.a = a;
this.next = next;
}
}
public boolean isEmpty() { return (first == null); }
public int size() { return N; }
public void insert(int a) {
first = new Node(a, first);
N++;
}
public static void main(String[] args) {
AdjList adjlist = new AdjList();
adjlist.insert(1);
adjlist.insert(2);
adjlist.insert(3);
adjlist.insert(4);
System.out.println(adjlist);
}
}
i am trying to write a code on adjacency list using linked list.data items are integers,but it shows error
this is the code i have tried .but it return some other values.can u help me
AdjList#6e1408 is the output
You need two toString() methods, perhaps something like this for the AdjList
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("AdjList [").append(N).append("] = {");
Node n = this.first;
for (int i = 0; i < N; i++) {
if (i != 0) {
sb.append(", ");
}
sb.append(n.toString());
n = n.next;
}
sb.append("}");
return sb.toString();
}
Then for your Node you need another one, perhaps something like this
public String toString() {
return String.valueOf(a);
}
I think you will get something more like what you expected if you try those.
edit - I revised my code and replaced my original work with new code, still having similar issues
This data structures class I'm taking is my first programming course, so I'm a bit out of my element. The first project is really kicking my ass. It is to make a Reverse Polish Notation Calculator. It is more or less complete, just a lot of bugs. I have been spending hours tweaking my code but when I address one problem it unleashes another. I apologize in advance for my horrible programming skills.
public class ReversePolishStack {
class SinglyLinkList {
Node head = null;
public void push(float newData) {
Node cache = this.head;
this.head = new Node(newData, cache);
}
public float pop() {
float out = this.head.data;
head = head.next;
return out;
}
public void add(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num1+num2);
}
public void sub(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num2-num1);
}
public void div(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num2/num1);
}
public void mult(float num1, float num2) {
num1 = pop();
num2 = pop();
push(num1*num2);
}
class Node {
public float data;
public Node next;
public Node(float data, Node next) {
this.data = data;
this.next = next;
}
}
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ReversePolishStack rps = new ReversePolishStack();
SinglyLinkList sll = rps.new SinglyLinkList();
String entry;
do
{
System.out.print("Enter Expression:\n");
Scanner in = new Scanner(System.in);
entry =in.nextLine();
StringTokenizer st = new StringTokenizer(entry," ");
String s1;
int count = 0;
while (st.hasMoreElements())
{
if (entry.length()<4) {// for an error message not enough input
System.out.print("Not enough input"); break;
}
else if (count>1 && sll.head.next==null) {
System.out.print("Not enough operands"); break;
}
s1 = st.nextToken();
if((s1.equals("+") || s1.equals("-") || s1.equals("*") || s1.equals("/"))) {
if(s1.equals("+"))
sll.add(sll.head.data, sll.head.next.data);
else if(s1.equals("-"))
sll.sub(sll.head.data, sll.head.next.data);
else if(s1.equals("/")) {
if (sll.head.data==0) {
System.out.println("Division by Zero enounterd."); break;
}
sll.div(sll.head.data, sll.head.next.data);
}
else if(s1.equals("*"))
sll.mult(sll.head.data, sll.head.next.data);
else
System.out.print("Unrecognized input");break;
}
else {
sll.push(Float.parseFloat(s1));
}
count++;
}
System.out.println(sll.head.data);
sll.pop();
} while(entry.equals("0")== false); // typeing a single zero terminates
System.out.print("Thanks for using my RPN Calculator!");
}
}
I have been at this for awhile and I'm sure with every attempt at fixing a bug I also added to the convolution that is my code. Any help would be appreciated!
First of all you should take out from the main method the classes you have defined.
After that you'll get an error because an instance of the class singlyLinkList (singlyLinkList sll = new singlyLinkList();) has been created without creating the outer class (ReversePolishStack).
See as reference this link about nested classes.
I also put the Node class into the singlyLinkList class (btw you should rename this class as SinglyLinkList with the first letter capitalized).
I didn't get into the logic of your code but at least after these fixes your code will compile:
public class ReversePolishStack {
class singlyLinkList {
Node head = null;
public void push(float newData) {
Node cache = this.head;
this.head = new Node(newData, cache);
}
public float pop() {
float out = this.head.data;
head = head.next;
return out;
}
class Node {
public float data;
public Node next;
public Node(float data, Node next) {
this.data = data;
this.next = next;
}
}
}
/**
* #param args
* the command line arguments
*/
public static void main(String[] args) {
float number1;
float number2;
ReversePolishStack rps = new ReversePolishStack();
singlyLinkList sll = rps.new singlyLinkList();
System.out.print("Enter Expression:\n");
// from here will be the same as you wrote
}
}
I also suggest you to extract the logic of your program from your main method and create methods in the ReversePolishStack in order to use the oop concepts.
Hope this was useful!
Ciao!
As a portion of a first year assignment, I need to create a class which uses a provided linked list implementation to implement a provided stack interface which is then tested by another provided class. I was able to easily complete the assignment using my own LL; however, I was told that I needed to use the one provided.
Exception in thread "main" java.lang.NullPointerException
at StackLL.<init>(StackLL.java:21)
at StackTester.main(StackTester.java:91)
Now I get null pointer exceptions whenever I try and run it. I thought this was being caused by the tester trying to grab the size of the list before the LL is initialized, but that doesn't seem to be the case and I am stumped.
Any tips on what I can do to fix the bug so that I can hand in the rest of the assignment? Thanks :)
The provided linked list implementation
LinkedList.java
/**
* LinkedList - a simple linked list of ints
*/
public class LinkedList
{
Node head;
int count;
public LinkedList ()
{
head = null;
count = 0;
}
/**
* Adds the given item to the start of the list
*/
public void addToStart (int item)
{
Node newNode = new Node();
newNode.value = item;
if (head != null)
newNode.next = head;
head = newNode;
count++;
}
/**
* Adds the given item to the end of the list
*/
public void addToEnd (int item)
{
if (size() == 0)
{
addToStart (item);
}
else
{
Node n = head;
while (n.next != null)
n = n.next;
n.next = new Node(item);
count++;
}
}
/**
* Remove and return the first item in the list
*/
public int removeFromStart ()
{
if (size() == 0)
throw new EmptyListException();
int valtoReturn = head.value;
head = head.next;
count--;
return valtoReturn;
}
/**
* Remove and return the last item in the list
*/
public int removeFromEnd ()
{
if (size() == 0)
throw new EmptyListException();
if (size() == 1)
return removeFromStart();
else
{
Node n = head;
while (n.next.next != null)
n = n.next;
int valtoReturn = n.next.value;
n.next = null;
count--;
return valtoReturn;
}
}
/**
* Return the number of items contained in this list
*/
public int size ()
{
return count;
}
/**
* A basic node class
*/
private class Node
{
int value;
Node next;
Node()
{
}
Node (int value)
{
this.value = value;
}
}
// random testing code for the Linked List
public static void main (String [] args)
{
LinkedList l = new LinkedList();
l.addToStart (5);
int val = l.removeFromStart();
System.out.println (val == 5 ? "passed" : "failed");
System.out.println (l.size() == 0 ? "passed" : "failed");
for (int x = 0; x < 10; x++)
l.addToEnd (x);
System.out.println (l.size() == 10 ? "passed" : "failed");
while (l.size() > 0)
System.out.print (l.removeFromEnd() + " ");
System.out.println ();
}
}
/**
* The exception class when a removal action is performed on
* an empty list.
*/
class EmptyListException extends RuntimeException
{
public EmptyListException ()
{
super();
}
public EmptyListException (String s)
{
super(s);
}
}
My implementation
StackLL.java
/**
* A linked list implementation of the Stack ADT.
*
*/
public class StackLL implements Stack
{
// The linked list that will contain the values in the stack
private LinkedList values;
public int size()
{
return values.size();
}
public boolean isEmpty()
{
if (values.size() <= 0) {
return true;
}
return false;
}
public void push(int element)
{
values.addToStart(element);
}
public int pop() throws StackEmptyException
{
if (values.size() == 0) {
throw new StackEmptyException();
}
else {
return values.removeFromStart();
}
}
public int peek() throws StackEmptyException
{
if (values.size() == 0) {
throw new StackEmptyException();
}
else { //This is a pretty silly way to do this, but I can't think of any other way without making my own linked list method.
int elementVal = values.removeFromStart();
values.addToStart(elementVal);
return elementVal;
}
}
}
The Provided Interface
Stack.java
/**
* Stack.java
*
* A specification of the Stack ADT
*
*/
public interface Stack
{
int size();
boolean isEmpty();
void push (int element);
int pop() throws StackEmptyException;
int peek() throws StackEmptyException;
}
class StackEmptyException extends Exception
{
public StackEmptyException ()
{
super();
}
public StackEmptyException (String s)
{
super(s);
}
}
The Tester
StackTester.java
/**
* StackTester.java
*
* Some test cases for a stack.
*/
public class StackTester
{
public static void testOne (Stack s)
{
try
{
if (s.size() != 0 || !s.isEmpty())
System.out.println("1: Failed size or isEmpty.");
s.push(1);
s.push(2);
if (s.size() != 2 || s.isEmpty())
System.out.println("2: Failed size or isEmpty.");
if (!(s.pop() == 2))
System.out.println("3: Failed pop");
if (!(s.peek() == 1))
System.out.println("4: Failed peek");
if (!(s.pop() == 1))
System.out.println("5: Failed pop");
if (s.size() != 0 || !s.isEmpty() )
System.out.println("6: Failed size or isEmpty.");
}
catch (StackEmptyException e)
{
System.out.println(e);
}
}
public static void testTwo (Stack s)
{
try
{
for (int i = 0; i < 100; i++)
{
s.push(i);
}
if (s.size() != 100)
System.out.println("7: Failed size.");
for (int i = 99; i >= 0; i--)
{
if (!(s.pop() == i))
{
System.out.println("Failed pop for: " + i);
break;
}
}
}
catch (StackEmptyException e)
{
System.out.println("Failed testTwo.");
System.out.println(e);
}
}
public static void testThree (Stack s)
{
try {
while (!s.isEmpty())
s.pop();
}
catch (StackEmptyException e) {
System.out.println ("Failed empty stack test (popped on a non empty stack threw exception)");
}
try
{
s.pop();
System.out.println("Failed empty stack test.");
}
catch (StackEmptyException e)
{
/* If we get here, we
* passed the previous test.
*/
}
}
public static void main (String args[])
{
Stack s1 = new StackLL();
Stack s2 = new StackLL();
Stack s3 = new StackLL();
testOne(s1);
testTwo(s2);
testThree(s3);
}
}
You have private LinkedList values; in StackLL.
That says "this class has a field called values of type LinkedList". It does not assign an object to values, so when you try to access it, a NullPointerException occurs.
You should be able to fix it by assigning a value to values, i.e.:
private LinkedList values = new LinkedList();
(I don't know if you've learned about generics yet, but if you have, remember to add the type, e.g. LinkedList<Person>.)
Look at the line of code given in the error message (I'm assuming its the return statement in your size() function) and think about the meaning of NullPointerException -- the variable which is null is not yet initialized. Then ask yourself, do I expect this variable to be initialized here? If yes, then ask why isn't it and where should it be initialized? If no, then you have a logic error at the given location.
You aren't ever instantiating a LinkedList object in StackLL. So the first time you try to access it, it blows a NPE.