here is the code
I have a calculator class , right now it only accounts for numbers but im trying to get it to account for a variable and set the value of the variable to a specific number ie 5
sorry if i was unclear. when i run this calculator , and input 1+1 it gives me 2 as the answer. but i want to be able to include a varibable for example 3*x^2 or 3*y^2. with the value of the variable being 5. right now this code is unable to do that.
public class Calculator {
// Allowable mathematical operators
static final String operators = "+-*/%()^!";
private String strPostfix;
private String strInfix;
private char chrVariable;
private int intError;
/**
* Default constructor. Sets all local values to default values
*/
public Calculator() {
setEquation("");
}
/**
* Sets a new equation.
* #param equation The new equation.
* #remarks Note that this also resets all values stored same as creating a new object
*/
public void setEquation(String equation)
{
// Remove any spaces, as they aren't necessary
strInfix = equation.replace(" ", "").trim();
strPostfix = "";
chrVariable = '\0';
intError = -2;
}
/**
* Gets the character location of the error found. -1 means no error found.
* #return An integer specifying the location of the error.
*/
public int get_ErrorLocation()
{
return intError + 1;
}
/**
* Gets the operators being used
* #return The operators
*/
public String get_Operators()
{
return operators;
}
/**
* Gets the post fix equation stored in memory for this object
* #return A post fix equation stored in a string
*/
public String get_PostFix()
{
return strPostfix;
}
/**
* Gets the variable that is in the equation. '~' means no variable found.
* #return The variable being used in the equation.
*/
public char get_Variable()
{
return chrVariable;
}
/**
* Solves the equation stored in memory for this instance, and stores it in memory
* #return A solution to a pre-existing equation
* #throws NoEquationException Occurs when attempting to solve an equation that doesn't exist
* #throws DivisionByZeroException Thrown when attempting to divide by zero
* #throws InvalidEquationException Occurs if an equation is invalid for an undefined reason
* #throws ExistingVariableException Occurs when attempting to use two variables
* #throws InvalidCharacterException Occurs when an invalid character is entered
*/
public double Solve() throws NoEquationException, DivisionByZeroException, InvalidEquationException, InvalidCharacterException, ExistingVariableException
{
strPostfix = PostFix().trim();
System.out.println(strPostfix);
return SolvePost();
}
/**
* Determines the precendence of a give mathematical operator
* #param value The mathematical operator
* #return The precendence of the operator
*/
private short precedence(char value) {
switch (value) {
case '+':
case '-':
return 1;
case '*':
case '/':
case '%':
return 2;
case '!':
return 3;
case '^':
return 4;
default:
return -1;
}
}
/**
* Turns an infix equation into post-fix
* #return The post-fix equivalent of the equation
* #throws InvalidEquationException When an invalid equation is given
* #throws ExistingVariableException Occurs when attempting to use two variables
* #throws InvalidCharacterException Occurs when an invalid character is entered
* #throws NoEquationException Occurs when attempting to solve an equation that doesn't exist
*/
private String PostFix() throws InvalidEquationException, InvalidCharacterException, ExistingVariableException {
// Backup the equation
String infix = strInfix;
String postfix = "";
char current;
char chrVariable;
Stack<Character> stack = new Stack<Character>();
boolean hasDec = false;
// For every character in the string
for ( int idx = 0; idx < infix.length(); ++idx ) {
current = infix.charAt(idx);
// If it is a digit or letter , just add it to postfix
if ( Character.isDigit(current) ) {
postfix += current;
// If it is a decimal, make sure there is only one per number
}else if (Character.isLetter(current))
postfix+=current;
else if( current == '.' ) {
if (!hasDec)
postfix += String.valueOf(current);
else
throw new InvalidEquationException();
hasDec = true;
// Otherwise, its an operator
}
else {
postfix += " ";
hasDec = false;
char peek;
// If there's an opening brace, just push it to the stack
if ( current == '(' )
stack.push(current);
// If its a closing brace, find pop until you find the opening one
else if ( current == ')' ) {
while ( !stack.isEmpty() && stack.peek() != '(' ) {
postfix += stack.pop() + " ";
}
// If the stack is empty, '(' was not found, error
if (stack.isEmpty()) { throw new InvalidEquationException('('); }
// Remove the '(' from the list
stack.pop();
} else {
if ( current == '-' && ( idx == 0 || operators.contains(String.valueOf(infix.charAt(idx - 1))))) {
postfix += current;
} else {
short prec = precedence(current);
if ( prec == -1 ) {
intError = idx;
throw new InvalidCharacterException();
}
// Pop off everything that has greater or equal precedence
if ( !stack.isEmpty() ) {
peek = stack.peek();
while ( precedence(current) <= precedence(peek) ) {
postfix += stack.pop() + " ";
if ( !stack.isEmpty() )
peek = stack.peek();
else
break;
}
}
// Now add the current onto the stack
stack.push(current);
}
}
}
}
// Finally, empty out the stack
while ( !stack.isEmpty() ) {
postfix += " " + stack.pop();
}
postfix = postfix.trim();
while ( postfix.contains(" ") ) {
postfix = postfix.replaceAll(" ", " ");
}
return postfix;
}
/**
* Solves the post-fix equation
* #return The solution to the equation
* #throws NoEquationException Thrown when PostFix equation not set
* #throws DivisionByZeroException Thrown when attempting to divide by zero
* #throws InvalidEquationException When an invalid equation is given
*/
private double SolvePost() throws NoEquationException, DivisionByZeroException, InvalidEquationException {
// Make sure there is an equation to solve
if ( strPostfix.trim().isEmpty() )
throw new NoEquationException();
Stack<Double> stack = new Stack<Double>();
String tokens[] = strPostfix.split(" ");
for ( String current : tokens ) {
try {
// If its a number, just push it
stack.push(Double.parseDouble(current));
} catch (Exception e) {
// If its not an operator, there's a problem
if ( current.length() > 1 || !operators.contains(current) )
throw new InvalidEquationException();
// there must be two operands, otherwise there's a problem
double first = 0, second = 0;
try {
second = stack.pop();
if ( current.charAt(0) != '!' )
first = stack.pop();
} catch (Exception ex) {
throw new InvalidEquationException();
}
// Do the appropriate math
switch ( current.charAt(0) ) {
case '+':
stack.push(first + second);
break;
case '-':
stack.push(first - second);
break;
case '*':
stack.push(first * second);
break;
case '/':
// Make sure its not division by zero
if (second == 0) { throw new DivisionByZeroException(); }
stack.push(first / second);
break;
case '%':
stack.push(first % second);
break;
case '^':
stack.push(Math.pow(first, second));
break;
case '!':
if ( (int)second != second || second < 0 )
throw new InvalidEquationException();
int result = 1;
for ( int i = 2; i <= second; ++i )
result *= i;
stack.push((double)result);
break;
default:
// Anything else isn't valid
throw new InvalidEquationException();
}
}
}
return stack.pop();
}
}
Related
If i have this string infix expression 2*4+3-15/2 and i want as output the postfix expression without considering the priority of the operations like so
2 4 * 3 + 15 - 2 /
What modifications do i need to in this code sample to "remove" that priority. I took this code from geeksforgeeks here https://www.geeksforgeeks.org/stack-set-2-infix-to-postfix/. I find it a little difficult to change to meet what i want. Where should i start? thanks.
the current code gives me this output : 24*3+152/-
private int Prec(String ch)
{
switch (ch)
{
case "+":
case "-":
return 1;
case "*":
case "/":
return 2;
case "^":
return 3;
}
return -1;
}
private boolean isNumeric(String strNum) {
if (strNum == null) {
return false;
}
try {
double d = Double.parseDouble(strNum);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
private String infixToPostfix(String infixExpression){
// initializing empty String for result
StringBuilder postfixExpression = new StringBuilder(new String(""));
String[] infixExp = infixExpression.split(" ");
// initializing empty stack
Stack<String> stack = new Stack<>();
for (String token : infixExp) {
System.out.println(token+" ");
// If the scanned character is an operand, add it to output.
if (isNumeric(token))
postfixExpression.append(token);
// If the scanned character is an '(', push it to the stack.
else if (token.equals("("))
stack.push(token);
// If the scanned character is an ')', pop and output from the stack
// until an '(' is encountered.
else if (token.equals(")")) {
while (!stack.isEmpty() && !stack.peek().equals("("))
postfixExpression.append(stack.pop());
if (!stack.isEmpty() && !stack.peek().equals("("))
return "Invalid Expression"; // invalid expression
else
stack.pop();
} else // an operator is encountered
{
while (!stack.isEmpty() && Prec(token) <= Prec(stack.peek())) {
if (stack.peek().equals("("))
return "Invalid Expression";
postfixExpression.append(stack.pop());
}
stack.push(token);
}
}
// pop all the operators from the stack
while (!stack.isEmpty()){
if(stack.peek().equals("("))
return "Invalid Expression";
postfixExpression.append(stack.pop());
}
System.out.println(postfixExpression);
return postfixExpression.toString();
}
It seems you just need to reverse the order of each pair formed by an operator and a number. You could do this using regular expressions and replaceAll:
String infix = "2*4+3-15/2";
String postfix = infix.replaceAll("([*+-/])([0-9]+)", " $2 $1");
System.out.println(postfix);
Output:
2 4 * 3 + 15 - 2 /
I am trying to write the following method for a lab assignment but have become very stuck on it. We are working with binary search tree's and they have asked for this method "int sizeBelow(T high) returns the number of elements in the tree that are strictly less than high" If someone could help me figure out how to write this it would be really appreciated! Been stuck on this for way too long
package week11;
import java.util.Scanner;
import static week11.LinkedBST.Direction.*;
/**
* A binary tree implementation using links. We assume that the tree
* is not to store 'null' elements. In particular if the root node
* *is* null then the tree is empty. This can only occur if a tree
* is initially constructed with no arguments, or if we remove the
* only element from a tree.
*
* #author Michael Albert, Iain Hewson
*/
public class LinkedBST<T extends Comparable<T>> {
/** The element held at the root of this tree. */
private T root;
/** The left subtree of this tree. */
private LinkedBST<T> left;
/** The right subtree of this tree. */
private LinkedBST<T> right;
/**
* Creates a BST with the given value.
*
* #param value to store at the root of this LinkedBST.
*/
public LinkedBST(T value) {
root = value;
left = null;
right = null;
}
/**
* Creates a new empty BST.
*/
public LinkedBST() {
this(null);
}
/**
* Adds an element to this BST if it isn't already there.
*
* #param element an element to be added.
*/
public void add(T element) {
if (root == null) {
root = element;
}
int comparison = root.compareTo(element);
if (comparison > 0) {
if (left == null) {
left = new LinkedBST<T>(element);
} else {
left.add(element);
}
} else if (comparison < 0) {
if (right == null) {
right = new LinkedBST<T>(element);
} else {
right.add(element);
}
}
}
/**
* Returns the height of this tree.
*
* #return the height of this tree.
*/
public int height() {
int leftH = 0, rightH = 0;
if (root == null) {
return 0;
}
if (right != null) {
rightH = 1 + right.height();
}
if (left != null) {
leftH = 1 + left.height();
}
return Math.max(leftH, rightH);
}
/**
* Searches for the given target within this tree.
*
* #param target
* #return true if target is found, otherwise false.
*/
public boolean search(T target) {
boolean lefth = false, righth = false;
if (root == null) {
return false;
}
int comparison = root.compareTo(target);
if (comparison == 0) {
return true;
}
if (comparison > 0) {
if (left != null) {
lefth = left.search(target);
}
return lefth;
}
if (comparison < 0) {
if (right != null) {
righth = right.search(target);
}
return righth;
}
return false;
}
/**
* Returns the size of this BST.
*
* #return the size of this BST.
*/
public int size() {
int lefth = 0, righth = 0;
if (root == null) {
return 0;
}
if (right != null) {
righth = right.size();
}
if (left != null) {
lefth = left.size();
}
return 1 + lefth + righth;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code>.
*
* #param low the lower bound to use when counting elements.
* #return how many elements are greater than or equal to the
* parameter <code>low</code>.
*/
public int sizeAbove(T low) {
if (root == null) {
return 0;
}
return 0;
}
/**
* Returns how many elements are less than the parameter
* <code>high</code>.
*
* #param high the element to compare when counting elements.
* #return how many elements are less than the parameter
* <code>high</code>.
*/
public int sizeBelow(T high) {
// implement this for part 2
return 0;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code> and less than the parameter
* <code>high</code>.
*
* #param low the lower bound to use when counting elements.
* #param high the upper bound to use when counting elements.
* #return how many elements are between low (inclusive) and
* high (exclusive).
*/
public int sizeBetween(T low, T high) {
// implement this for part 2
return 0;
}
/**
* Removes the given element from this tree if it is present.
*
* #param element the element to remove.
*/
public void remove(T element) {
// implement this method from the lectures if you
// want to do the extension exercises
}
/** The direction used when creating a representation of this tree. */
enum Direction {LEFT, RIGHT, NO};
/**
* Recursively generates a representation of this tree.
*
* #param curr the current line being generated.
* #param dir the direction of the last link followed.
* #param result the representation generated so far.
* #return a representation of this tree.
*/
public StringBuilder str(String curr, Direction dir, StringBuilder result) {
if(right != null) {
right.str(curr + (dir == LEFT ? "│ " : " "), RIGHT, result);
}
if (root != null) {
result.append(curr + (dir == RIGHT ? "┌─ " :
dir == LEFT ? "└─ " : " ") + root + "\n");
}
if(left != null) {
left.str(curr + (dir == RIGHT ? "│ " : " "), LEFT, result);
}
return result;
}
#Override
public String toString() {
return str("", NO, new StringBuilder()).toString();
}
/**
* Entry point of program (used for testing).
* Valid commands are:
* <pre>
* a (add) item(s) - calls add with each item
* f (find) item - calls search with item
* p (print) - calls toString
* h (height) - calls height
* s (size) - calls size
* sa (sizeabove) low - calls sizeAbove(low)
* sb (sizebelow) high - calls sizeBelow(high)
* si (sizeinbetween) low high - calls sizeBetween(low,high)
* </pre>
* Return values of methods are printed to stdout.
*
* #param args command line arguments are not used.
*/
public static void main(String[] args) {
LinkedBST<String> tree = new LinkedBST<>();
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
Scanner line = new Scanner(input.nextLine());
if (line.hasNext()) {
String command = line.next();
switch (command) {
case "a": case "add":
while (line.hasNext()) {
tree.add(line.next());
}
break;
case "f": case "find":
if (line.hasNext()) {
System.out.println(tree.search(line.next()));
}
break;
case "p": case "print":
System.out.print(tree);
break;
case "h": case "height":
System.out.println(tree.height());
break;
case "s": case "size":
System.out.println(tree.size());
break;
case "sa": case "sizeabove":
if (line.hasNext()) {
String low = line.next();
System.out.println(tree.sizeAbove(low));
}
break;
case "sb": case "sizebelow":
if (line.hasNext()) {
package week11;
import java.util.Scanner;
import static week11.LinkedBST.Direction.*;
/**
* A binary tree implementation using links. We assume that the tree
* is not to store 'null' elements. In particular if the root node
* *is* null then the tree is empty. This can only occur if a tree
* is initially constructed with no arguments, or if we remove the
* only element from a tree.
*
* #author Michael Albert, Iain Hewson
*/
public class LinkedBST<T extends Comparable<T>> {
/** The element held at the root of this tree. */
private T root;
/** The left subtree of this tree. */
private LinkedBST<T> left;
/** The right subtree of this tree. */
private LinkedBST<T> right;
/**
* Creates a BST with the given value.
*
* #param value to store at the root of this LinkedBST.
*/
public LinkedBST(T value) {
root = value;
left = null;
right = null;
}
/**
* Creates a new empty BST.
*/
public LinkedBST() {
this(null);
}
/**
* Adds an element to this BST if it isn't already there.
*
* #param element an element to be added.
*/
public void add(T element) {
if (root == null) {
root = element;
}
int comparison = root.compareTo(element);
if (comparison > 0) {
if (left == null) {
left = new LinkedBST<T>(element);
} else {
left.add(element);
}
} else if (comparison < 0) {
if (right == null) {
right = new LinkedBST<T>(element);
} else {
right.add(element);
}
}
}
/**
* Returns the height of this tree.
*
* #return the height of this tree.
*/
public int height() {
int leftH = 0, rightH = 0;
if (root == null) {
return 0;
}
if (right != null) {
rightH = 1 + right.height();
}
if (left != null) {
leftH = 1 + left.height();
}
return Math.max(leftH, rightH);
}
/**
* Searches for the given target within this tree.
*
* #param target
* #return true if target is found, otherwise false.
*/
public boolean search(T target) {
boolean lefth = false, righth = false;
if (root == null) {
return false;
}
int comparison = root.compareTo(target);
if (comparison == 0) {
return true;
}
if (comparison > 0) {
if (left != null) {
lefth = left.search(target);
}
return lefth;
}
if (comparison < 0) {
if (right != null) {
righth = right.search(target);
}
return righth;
}
return false;
}
/**
* Returns the size of this BST.
*
* #return the size of this BST.
*/
public int size() {
int lefth = 0, righth = 0;
if (root == null) {
return 0;
}
if (right != null) {
righth = right.size();
}
if (left != null) {
lefth = left.size();
}
return 1 + lefth + righth;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code>.
*
* #param low the lower bound to use when counting elements.
* #return how many elements are greater than or equal to the
* parameter <code>low</code>.
*/
public int sizeAbove(T low) {
if (root == null) {
return 0;
}
return 0;
}
/**
* Returns how many elements are less than the parameter
* <code>high</code>.
*
* #param high the element to compare when counting elements.
* #return how many elements are less than the parameter
* <code>high</code>.
*/
public int sizeBelow(T high) {
// implement this for part 2
return 0;
}
/**
* Returns how many elements are greater than or equal to the
* parameter <code>low</code> and less than the parameter
* <code>high</code>.
*
* #param low the lower bound to use when counting elements.
* #param high the upper bound to use when counting elements.
* #return how many elements are between low (inclusive) and
* high (exclusive).
*/
public int sizeBetween(T low, T high) {
// implement this for part 2
return 0;
}
/**
* Removes the given element from this tree if it is present.
*
* #param element the element to remove.
*/
public void remove(T element) {
// implement this method from the lectures if you
// want to do the extension exercises
}
/** The direction used when creating a representation of this tree. */
enum Direction {LEFT, RIGHT, NO};
/**
* Recursively generates a representation of this tree.
*
* #param curr the current line being generated.
* #param dir the direction of the last link followed.
* #param result the representation generated so far.
* #return a representation of this tree.
*/
public StringBuilder str(String curr, Direction dir, StringBuilder result) {
if(right != null) {
right.str(curr + (dir == LEFT ? "│ " : " "), RIGHT, result);
}
if (root != null) {
result.append(curr + (dir == RIGHT ? "┌─ " :
dir == LEFT ? "└─ " : " ") + root + "\n");
}
if(left != null) {
left.str(curr + (dir == RIGHT ? "│ " : " "), LEFT, result);
}
return result;
}
#Override
public String toString() {
return str("", NO, new StringBuilder()).toString();
}
/**
* Entry point of program (used for testing).
* Valid commands are:
* <pre>
* a (add) item(s) - calls add with each item
* f (find) item - calls search with item
* p (print) - calls toString
* h (height) - calls height
* s (size) - calls size
* sa (sizeabove) low - calls sizeAbove(low)
* sb (sizebelow) high - calls sizeBelow(high)
* si (sizeinbetween) low high - calls sizeBetween(low,high)
* </pre>
* Return values of methods are printed to stdout.
*
* #param args command line arguments are not used.
*/
public static void main(String[] args) {
LinkedBST<String> tree = new LinkedBST<>();
Scanner input = new Scanner(System.in);
while (input.hasNextLine()) {
Scanner line = new Scanner(input.nextLine());
if (line.hasNext()) {
String command = line.next();
switch (command) {
case "a": case "add":
while (line.hasNext()) {
tree.add(line.next());
}
break;
case "f": case "find":
if (line.hasNext()) {
System.out.println(tree.search(line.next()));
}
break;
case "p": case "print":
System.out.print(tree);
break;
case "h": case "height":
System.out.println(tree.height());
break;
case "s": case "size":
System.out.println(tree.size());
break;
case "sa": case "sizeabove":
if (line.hasNext()) {
String low = line.next();
System.out.println(tree.sizeAbove(low));
}
break;
case "sb": case "sizebelow":
if (line.hasNext()) {
System.out.println(tree.sizeBelow(line.next()));
}
break;
case "si": case "sizeinbetween":
if (line.hasNext()) {
String low = line.next();
if (line.hasNext()) {
System.out.println(tree.sizeBetween
(low, line.next()));
}
}
break;
default:
System.err.println("Unknown command: " + command);
}
}
}
}
}
System.out.println(tree.sizeBelow(line.next()));
}
break;
case "si": case "sizeinbetween":
if (line.hasNext()) {
String low = line.next();
if (line.hasNext()) {
System.out.println(tree.sizeBetween
(low, line.next()));
}
}
break;
default:
System.err.println("Unknown command: " + command);
}
}
}
}
}
As this is homework I will try to point you in the right direction rather than do it for you. The task at hand is better solved with recursion and when it comes to binary trees, there are several different types of traversals that can be done recursively.
In-order traversal (LVR)
Reverse order traversal (RVL)
Preorder traversal (VLR)
Postorder traversal (LRV)
I would perform an In-order traversal and increment accordingly if we find any value below high.
Hint:
you'll need to create an inOrder method which takes an argument of the root and an argument of T high and recursively traverse down the tree checking if the current node value is less that high.
public int sizeBelow(T high) {
// return inOrder(root,high);
}
private int inOrder(type current, type high){
// check if ANY of root or high are null (if yes return 0)
// recursively go down the tree comparing current against high
// if current is less than high then return 1 + inOrder(...,high)
// all other conditions should return 0.
}
Ensure you read on Tree Traversals (Inorder, Preorder and Postorder). When you click on this link ensure you select the JAVA tab because by default the examples are shown in C.
I have four classes.
One contains my linkedstack setup
One is infixtopostfix for prioritization and conversion
Parenthesis for matching
Postfix for evaluation
I have setup almost everything here but it is still returning false anyway I put it.
On another note my equals on !stackMatch.pop().equals(c) is not working due to it being a object type with '!' being a problem.
My programs are simple and straight forward:
LinkedStack.java
public class LinkedStack implements StackInterface {
private Node top;
public LinkedStack() {
top = null;
} // end default constructor
public boolean isEmpty() {
return top == null;
} // end isEmpty
public void push(Object newItem) {
Node n = new Node();
n.setData(newItem);
n.setNext(top);
top = n;
} // end push
public Object pop() throws Exception {
if (!isEmpty()) {
Node temp = top;
top = top.getNext();
return temp.getData();
} else {
throw new Exception("StackException on pop: stack empty");
} // end if
} // end pop
public Object peek() throws Exception {
if (!isEmpty()) {
return top.getData();
} else {
throw new Exception("StackException on peek: stack empty");
} // end if
} // end peek
} // end LinkedStack
InfixToPostfix.java
import java.util.*;
public class InfixToPostfix {
Parenthesis p = new Parenthesis();
LinkedStack stack = new LinkedStack();
String token = ""; // each token of the string
String output = ""; // the string holding the postfix expression
Character topOfStackObject = null; // the top object of the stack, converted to a Character Object
char charValueOfTopOfStack = ' '; // the primitive value of the Character object
/**
* Convert an infix expression to postfix. If the expression is invalid, throws an exception.
* #param s the infix expression
* #return the postfix expression as a string
* hint: StringTokenizer is very useful to this iteratively
*/
//public String convertToPostfix(String s) throws Exception {
//}
private boolean isOperand (char c){
return ((c>= '0' && c <= '9') || (c >= 'a' && c<= 'z'));
}
public void precedence(char curOp, int val) throws Exception {
while (!stack.isEmpty()) {
char topOp = (Character) stack.pop();
// charValueOfTopOfStack = topOfStackObject.charValue();
if (topOp == '(') {
stack.push(topOp);
break;
}// it's an operator
else {// precedence of new op
int prec2;
if (topOp == '+' || topOp == '-') {
prec2 = 1;
} else {
prec2 = 2;
}
if (prec2 < val) // if prec of new op less
{ // than prec of old
stack.push(topOp); // save newly-popped op
break;
} else // prec of new not less
{
output = output + topOp; // than prec of old
}
}
}
}
Parenthesis.java
import java.util.*;
public class Parenthesis{
private LinkedStack stack = new LinkedStack();
private Object openBrace;
private String outputString;
/**
* Determine if the expression has matching parenthesis using a stack
*
* #param expr the expression to be evaluated
* #return returns true if the expression has matching parenthesis
*/
public boolean match(String expr) {
LinkedStack stackMatch = new LinkedStack();
for(int i=0; i < expr.length(); i++) {
char c = expr.charAt(i);
if(c == '(')
stackMatch.push(c);
else if(c == ')'){
if (stackMatch.isEmpty() || !stackMatch.pop().equals(c))
return false;
}
}
return stackMatch.isEmpty();
}
}
Just wanted to give you all of it so you could help me. I have tests written already just struggling with the parenthesis problem of pushing it on the stack but unable to compare it to the closing parenthesis so it can check if there is enough while checking to be sure it is not empty.
The problem probably is, that you are trying to test if matching ( is currently on top of the stack when ) comes, but in c is acctual character, ), so you test if ) is on top of stack, not ( as you should.
I am trying to modify a config file in Java using Properties.
I read, write and modify the lines successfully using Properties.store, load and setProperty, but I noticed that after doing such operation the file is overwritten and thus I loose al the lines in the config file that are not key-value pairs. Namely, I loose the comments.
Is there a way to keep such lines using java.util?
Placing a prefix in each line is not a problem. I know how to do it 'manually' reading line by line; I'am asking instead for an alternative
I don't think it is possible. Note that properties also don't promise that the ordering will be the same from load() to store(), or from one store() to another. If it is possible, the javadoc for Properties will tell you how.
import java.io.*;
import java.util.*;
/**
* The CommentedProperties class is an extension of java.util.Properties
* to allow retention of comment lines and blank (whitespace only) lines
* in the properties file.
*
* Written for Java version 1.4
*/
public class CommentedProperties extends java.util.Properties {
/**
* Use a Vector to keep a copy of lines that are a comment or 'blank'
*/
public Vector lineData = new Vector(0, 1);
/**
* Use a Vector to keep a copy of lines containing a key, i.e. they are a property.
*/
public Vector keyData = new Vector(0, 1);
/**
* Load properties from the specified InputStream.
* Overload the load method in Properties so we can keep comment and blank lines.
* #param inStream The InputStream to read.
*/
public void load(InputStream inStream) throws IOException
{
// The spec says that the file must be encoded using ISO-8859-1.
BufferedReader reader =
new BufferedReader(new InputStreamReader(inStream, "ISO-8859-1"));
String line;
while ((line = reader.readLine()) != null) {
char c = 0;
int pos = 0;
// Leading whitespaces must be deleted first.
while ( pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos))) {
pos++;
}
// If empty line or begins with a comment character, save this line
// in lineData and save a "" in keyData.
if ( (line.length() - pos) == 0
|| line.charAt(pos) == '#' || line.charAt(pos) == '!') {
lineData.add(line);
keyData.add("");
continue;
}
// The characters up to the next Whitespace, ':', or '='
// describe the key. But look for escape sequences.
// Try to short-circuit when there is no escape char.
int start = pos;
boolean needsEscape = line.indexOf('\\', pos) != -1;
StringBuffer key = needsEscape ? new StringBuffer() : null;
while ( pos < line.length()
&& ! Character.isWhitespace(c = line.charAt(pos++))
&& c != '=' && c != ':') {
if (needsEscape && c == '\\') {
if (pos == line.length()) {
// The line continues on the next line. If there
// is no next line, just treat it as a key with an
// empty value.
line = reader.readLine();
if (line == null)
line = "";
pos = 0;
while ( pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos)))
pos++;
} else {
c = line.charAt(pos++);
switch (c) {
case 'n':
key.append('\n');
break;
case 't':
key.append('\t');
break;
case 'r':
key.append('\r');
break;
case 'u':
if (pos + 4 <= line.length()) {
char uni = (char) Integer.parseInt
(line.substring(pos, pos + 4), 16);
key.append(uni);
pos += 4;
} // else throw exception?
break;
default:
key.append(c);
break;
}
}
} else if (needsEscape)
key.append(c);
}
boolean isDelim = (c == ':' || c == '=');
String keyString;
if (needsEscape)
keyString = key.toString();
else if (isDelim || Character.isWhitespace(c))
keyString = line.substring(start, pos - 1);
else
keyString = line.substring(start, pos);
while ( pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos)))
pos++;
if (! isDelim && (c == ':' || c == '=')) {
pos++;
while ( pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos)))
pos++;
}
// Short-circuit if no escape chars found.
if (!needsEscape) {
put(keyString, line.substring(pos));
// Save a "" in lineData and save this
// keyString in keyData.
lineData.add("");
keyData.add(keyString);
continue;
}
// Escape char found so iterate through the rest of the line.
StringBuffer element = new StringBuffer(line.length() - pos);
while (pos < line.length()) {
c = line.charAt(pos++);
if (c == '\\') {
if (pos == line.length()) {
// The line continues on the next line.
line = reader.readLine();
// We might have seen a backslash at the end of
// the file. The JDK ignores the backslash in
// this case, so we follow for compatibility.
if (line == null)
break;
pos = 0;
while ( pos < line.length()
&& Character.isWhitespace(c = line.charAt(pos)))
pos++;
element.ensureCapacity(line.length() - pos +
element.length());
} else {
c = line.charAt(pos++);
switch (c) {
case 'n':
element.append('\n');
break;
case 't':
element.append('\t');
break;
case 'r':
element.append('\r');
break;
case 'u':
if (pos + 4 <= line.length()) {
char uni = (char) Integer.parseInt
(line.substring(pos, pos + 4), 16);
element.append(uni);
pos += 4;
} // else throw exception?
break;
default:
element.append(c);
break;
}
}
} else
element.append(c);
}
put(keyString, element.toString());
// Save a "" in lineData and save this
// keyString in keyData.
lineData.add("");
keyData.add(keyString);
}
}
/**
* Write the properties to the specified OutputStream.
*
* Overloads the store method in Properties so we can put back comment
* and blank lines.
*
* #param out The OutputStream to write to.
* #param header Ignored, here for compatability w/ Properties.
*
* #exception IOException
*/
public void store(OutputStream out, String header) throws IOException
{
// The spec says that the file must be encoded using ISO-8859-1.
PrintWriter writer
= new PrintWriter(new OutputStreamWriter(out, "ISO-8859-1"));
// We ignore the header, because if we prepend a commented header
// then read it back in it is now a comment, which will be saved
// and then when we write again we would prepend Another header...
String line;
String key;
StringBuffer s = new StringBuffer ();
for (int i=0; i<lineData.size(); i++) {
line = (String) lineData.get(i);
key = (String) keyData.get(i);
if (key.length() > 0) { // This is a 'property' line, so rebuild it
formatForOutput (key, s, true);
s.append ('=');
formatForOutput ((String) get(key), s, false);
writer.println (s);
} else { // was a blank or comment line, so just restore it
writer.println (line);
}
}
writer.flush ();
}
/**
* Need this method from Properties because original code has StringBuilder,
* which is an element of Java 1.5, used StringBuffer instead (because
* this code was written for Java 1.4)
*
* #param str - the string to format
* #param buffer - buffer to hold the string
* #param key - true if str the key is formatted, false if the value is formatted
*/
private void formatForOutput(String str, StringBuffer buffer, boolean key)
{
if (key) {
buffer.setLength(0);
buffer.ensureCapacity(str.length());
} else
buffer.ensureCapacity(buffer.length() + str.length());
boolean head = true;
int size = str.length();
for (int i = 0; i < size; i++) {
char c = str.charAt(i);
switch (c) {
case '\n':
buffer.append("\\n");
break;
case '\r':
buffer.append("\\r");
break;
case '\t':
buffer.append("\\t");
break;
case ' ':
buffer.append(head ? "\\ " : " ");
break;
case '\\':
case '!':
case '#':
case '=':
case ':':
buffer.append('\\').append(c);
break;
default:
if (c < ' ' || c > '~') {
String hex = Integer.toHexString(c);
buffer.append("\\u0000".substring(0, 6 - hex.length()));
buffer.append(hex);
} else
buffer.append(c);
}
if (c != ' ')
head = key;
}
}
/**
* Add a Property to the end of the CommentedProperties.
*
* #param keyString The Property key.
* #param value The value of this Property.
*/
public void add(String keyString, String value)
{
put(keyString, value);
lineData.add("");
keyData.add(keyString);
}
/**
* Add a comment or blank line or comment to the end of the CommentedProperties.
*
* #param line The string to add to the end, make sure this is a comment
* or a 'whitespace' line.
*/
public void addLine(String line)
{
lineData.add(line);
keyData.add("");
}
}
I'm having trouble implementing a stack as an array in java. When I try to utilize the array, I get nullPointerExceptions. I know that the rest of my code works because I'm able to run the program using the linked list implementation of the stack I have created. The code is below:
Edit: The stack trace is
Exception in thread "main" java.lang.NullPointerException
at LispEvaluator.evaluate(LispEvaluator.java:238)
at LispEvaluator.fileLoader(LispEvaluator.java:67)
at Driver.main(Driver.java:16)
Here is the code for the lispEvaluator class
//code starts here
import java.util.*;
import java.io.*;
public class LispEvaluator {
// Current input Lisp expression
private String inputExpr;
private Scanner sc;
private StackList exprStack;
private StackList tempStack;
// default constructor
// set inputExpr to ""
// create stack objects
public LispEvaluator()
{
inputExpr = "";
}
// default constructor
// set inputExpr to inputExpression
// create stack objects
public LispEvaluator(String inputExpression)
{
inputExpr = inputExpression;
}
// set inputExpr to inputExpression
// clear stack objects
public void reset(String inputExpression)
{
inputExpr = inputExpression;
StackList exprStack=new StackList(50);
StackList tempStack=new StackList(50);
}
private boolean checkifNumber() {
return false;
}
public void fileLoader(String mode,String file){
//Validate the user entered mode
if(mode.equals("0")){
exprStack=new StackList(50);
tempStack=new StackList(50);}
else{
ArrayStack exprStack=new ArrayStack(50);
ArrayStack tempStack=new ArrayStack(50);
}
try{
//Try to read the array from file
sc = new Scanner(new File(file));
while (sc.hasNextLine()) {
double result=0;
inputExpr=sc.nextLine();
reset(inputExpr);
result=evaluate();
System.out.println(result);
}
}
catch (FileNotFoundException e){
System.out.println("Cannot find requested input file");
}
catch(IOException io){
System.out.println("General file io error occured. Try again");
}
}
// This function evaluate current operator with its operands
// See complete algorithm in evaluate()
//
// Main Steps:
// Pop operands from expressionStack and push them onto
// tempStack until you find an operator
// Apply the operator to the operands on tempStack
// Push the result into expressionStack
//
private double add() {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp + op2;}
return temp;
}
private double multiply() {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp * op2;}
return temp;
}
private double subtract() {
if (tempStack.size() == 1) {
double temp = -1*(Double) tempStack.pop();
return temp;
} else {
double op1 = (Double) tempStack.pop();
double temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp - op2;}
return temp;
}
}
private double divide() {
double temp;
if (tempStack.size() == 1) {
temp = 1 / (Double) tempStack.pop();
return temp;
}
else if (tempStack.size() >=1) {
double op1 = (Double) tempStack.pop();
temp=op1;
while (tempStack.size()>0){
double op2 = (Double) tempStack.pop();
temp = temp / op2;}
return temp;
}
return 0;
}
private void evaluateCurrentOperation()
{
while( exprStack.top().getClass().getName().equals("java.lang.Double") ) {
tempStack.push( (Double)exprStack.pop() );
}
Character operator = (Character)exprStack.pop();
Double result = null;
switch( operator ) {
case '+':
result = add();
break;
case '*':
result = multiply();
break;
case '-':
result = subtract();
break;
case '/':
result = divide();
break;
}
exprStack.push( result );
}
/**
* This function evaluates Lisp expression in inputExpr
* It return result of the expression
*
* The algorithm:
*
* Step 1 Scan the tokens in the expression string.
* Step 2 If you see an operand, push operand object onto the expressionStack
* Step 3 If you see "(", next token should be an operator
* Step 4 If you see an operator, push operator object onto the expressionStack
* Step 5 If you see ")" // steps in evaluateCurrentOperation() :
* Step 6 Pop operands and push them onto tempStack
* until you find an operator
* Step 7 Apply the operator to the operands on tempStack
* Step 8 Push the result into expressionStack
* Step 9 If you run out of tokens, the value on the top of expressionStack is
* is the result of the expression.
*/
public double evaluate()
{
// only outline is given...
// you need to add statements
// you may delete or modify any statements in this method
// use scanner to tokenize inputExpr
Scanner inputExprScanner = new Scanner(inputExpr);
// Use zero or more white space as delimiter,
// which breaks the string into single character tokens
inputExprScanner = inputExprScanner.useDelimiter("\\s*");
// Step 1: Scan the tokens in the string.
while (inputExprScanner.hasNext())
{
// Step 2: If you see an operand, push operand object onto the expressionStack
if (inputExprScanner.hasNextInt())
{
// This force scanner to grab all of the digits
// Otherwise, it will just get one char
String dataString = inputExprScanner.findInLine("\\d+");
exprStack.push(new Double(dataString));
// more ...
}
else
{
// Get next token, only one char in string token
String aToken = inputExprScanner.next();
char item = aToken.charAt(0);
String nextToken;
char nextItem;
switch (item)
{
// Step 3: If you see "(", next token should be an operator
case '(':
nextToken = inputExprScanner.next();
nextItem = nextToken.charAt(0);
// Step 4: If you see an operator, push operator object onto the expressionStack
if (nextItem == '+') {
exprStack.push(nextItem);
} else if (nextItem == '-') {
exprStack.push(nextItem);
} else if (nextItem == '*') {
exprStack.push(nextItem);
}else if (nextItem == '/'){
exprStack.push(nextItem);
}
else {
exprStack.push(nextItem);
}
break;
// Step 5: If you see ")" // steps 6,7,8 in evaluateCurrentOperation()
case ')':
try {
evaluateCurrentOperation();
} catch (EmptyStackException e) {
break;
}
break;
default: // error
throw new RuntimeException(item + " is not a legal expression operator");
} // end switch
} // end else
} // end while
// Step 9: If you run out of tokens, the value on the top of expressionStack is
// is the result of the expression.
//
// return result
double result = (Double) exprStack.pop();
return result;
}
}
/*
// This static method is used by main() only
private static void evaluateExprt(String s, SimpleLispExpressionEvaluator expr)
{
Double result;
System.out.println("Expression " + s);
expr.reset(s);
result = expr.evaluate();
System.out.printf("Result %.2f\n", result);
System.out.println("-----------------------------");
}
// simple tests
public static void main (String args[])
{
SimpleLispExpressionEvaluator expr= new SimpleLispExpressionEvaluator();
String test1 = "(+ (- 6) (* 2 3 4) (/ (+ 3) (* 1) (- 2 3 1)))";
String test2 = "(+ (- 632) (* 21 3 4) (/ (+ 32) (* 1) (- 21 3 1)))";
String test3 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 1) (- 2 1 )))";
String test4 = "(+ (/2))";
String test5 = "(+ (/2 3 0))";
String test6 = "(+ (/ 2) (* 2) (/ (+ 1) (+ 3) (- 2 1 ))))";
evaluateExprt(test1, expr);
evaluateExprt(test2, expr);
evaluateExprt(test3, expr);
evaluateExprt(test4, expr);
evaluateExprt(test5, expr);
evaluateExprt(test6, expr);
} }
*/
And heres the Array Stack:
public class ArrayStack implements BoundedStack
{
private int top;
private Object stk[];
private int size;
private int capacity;
public ArrayStack(){
top=-1;
capacity=50;
stk=new Object[capacity];
}
public ArrayStack(int cap)
{
top=-1;
size=0;
capacity=cap;
stk=new Object[capacity];
}
public void push(Object item) throws FullStackException
{
if(isFull()){
throw new FullStackException("The stack is full. Cannot push more elements onto the stack");}
else
{
stk[++top]=item;
}
}
public Object pop() throws EmptyStackException
{
if(isEmpty()==true)
{
throw new EmptyStackException("The stack is empty. Cannot pop another element from the stack");
}
else{
Object e=stk[top];
stk [top]=null;
--top;
return e;
}
}
public Object top() throws EmptyStackException{
if(isEmpty()==true){
throw new EmptyStackException("The stack is empty. Thus, it has no top");
}
return stk[top];
}
public int size(){
return (top+1);
}
public boolean isFull(){
if (size()==capacity){
return true;}
return false;
}
public boolean isEmpty(){
if(size()==0){
return true;}
return false;
}
public int capacity(){
return capacity;
}
}
The most obvious reason for this is you have not initialized your array elements before using it.
If you are creating an array like: -
SomeClass[] arr = new SomeClass[5];
Then before using your array, you need to initialize each array elements like this: -
for (int i = 0; i < arr.length; i++) {
arr[i] = new SomeClass();
}
If the line causing the NullPointerException is the line
exprStack.push(nextItem);
then the problem is not in the stack class. The problem is that exprStack is null (probably because it has never been assigned anything before this line).
You're making the same error as the following one several times in your code:
public void reset(String inputExpression) {
inputExpr = inputExpression;
StackList exprStack=new StackList(50);
StackList tempStack=new StackList(50);
}
The two last lines are completely useless: they assign a new StackList to a local variable. So the stack is created, and is immediately eligible to garbage collection, since nothing references it except a local variable that goes out of scope.
Here's another place where it happens:
if (mode.equals("0")){
exprStack=new StackList(50);
tempStack=new StackList(50);
}
else {
ArrayStack exprStack=new ArrayStack(50);
ArrayStack tempStack=new ArrayStack(50);
}