So i have this function EDIT:Whole program as requested
//This is a java program to construct Expression Tree using Infix Expression
import java.io.*;
public class Infix_Expression_Tree
{
public static void main(String args[]) throws IOException
{
String result="";
File vhod = new File(args[0]);
try{
BufferedReader reader = new BufferedReader(new FileReader(vhod));
Tree t1 = new Tree();
String a = reader.readLine();
t1.insert(a);
t1.traverse(1,result);
System.out.println("rez "+ result);
ch = reader.readLine();
}catch(IOException e){
e.printStackTrace();
}
}
}
class Node
{
public char data;
public Node leftChild;
public Node rightChild;
public Node(char x)
{
data = x;
}
public void displayNode()
{
System.out.print(data);
}
}
class Stack1
{
private Node[] a;
private int top, m;
public Stack1(int max)
{
m = max;
a = new Node[m];
top = -1;
}
public void push(Node key)
{
a[++top] = key;
}
public Node pop()
{
return (a[top--]);
}
public boolean isEmpty()
{
return (top == -1);
}
}
class Stack2
{
private char[] a;
private int top, m;
public Stack2(int max)
{
m = max;
a = new char[m];
top = -1;
}
public void push(char key)
{
a[++top] = key;
}
public char pop()
{
return (a[top--]);
}
public boolean isEmpty()
{
return (top == -1);
}
}
class Conversion
{
private Stack2 s;
private String input;
private String output = "";
public Conversion(String str)
{
input = str;
s = new Stack2(str.length());
}
public String inToPost()
{
for (int i = 0; i < input.length(); i++)
{
char ch = input.charAt(i);
switch (ch)
{
case '+':
gotOperator(ch, 2);
break;
case '*':
gotOperator(ch,1);
break;
case '/':
gotOperator(ch, 3);
break;
case '(':
s.push(ch);
break;
case ')':
gotParenthesis();
//s.pop();
break;
default:
//gotOperator(ch, 0);
//break;
output = output + ch;
}
}
while (!s.isEmpty())
output = output + s.pop();
//System.out.println("to je output iz inToPost " +output);
return output;
}
private void gotOperator(char opThis, int prec1)
{
while (!s.isEmpty())
{
char opTop = s.pop();
if (opTop == '(')
{
s.push(opTop);
break;
} else
{
int prec2;
if (opTop == '+')
prec2 = 2;
else if(opTop=='*')
prec2=1;
else
prec2 = 3;
if (prec2 <= prec1)
{
s.push(opTop);
break;
} else
output = output + opTop;
}
}
s.push(opThis);
}
private void gotParenthesis()
{
while (!s.isEmpty())
{
char ch = s.pop();
if (ch == '(')
break;
else
output = output + ch;
}
}
}
class Tree
{
private Node root;
public Tree()
{
root = null;
}
public void insert(String s)
{
Conversion c = new Conversion(s);
s = c.inToPost();
Stack1 stk = new Stack1(s.length());
s = s + "#";
int i = 0;
char symbol = s.charAt(i);
Node newNode;
while (symbol != '#')
{
if (symbol >= '0' && symbol <= '9' || symbol >= 'A'
&& symbol <= 'Z' || symbol >= 'a' && symbol <= 'z')
{
newNode = new Node(symbol);
stk.push(newNode);
} else if (symbol == '+' || symbol == '/'
|| symbol == '*')
{
Node ptr1=null;
Node ptr2=null;
//if(!stk.isEmpty()){
ptr1 = stk.pop();
if(!stk.isEmpty()){
ptr2 = stk.pop();
}
//}
newNode = new Node(symbol);
newNode.leftChild = ptr2;
newNode.rightChild = ptr1;
stk.push(newNode);
}
/*else if(symbol=='/'){
Node ptr = stk.pop();
newNode = new Node(symbol);
newNode.leftChild = ptr;
newNode.rightChild=null;
stk.push(newNode);
}*/
symbol = s.charAt(++i);
}
root = stk.pop();
}
public void traverse(int type,String result)
{
System.out.println("Preorder Traversal:- ");
preOrder(root,result);
}
private void preOrder(Node localRoot, String result)
{
if(root==null){
return;
}
if (localRoot != null)
{
if(localRoot.data == '/'){
preOrder(localRoot.leftChild,result);
result=result + localRoot.data;
//StringBuilder stringBuilder1 = new StringBuilder();
//stringBuilder1.append(result).append(localRoot.data);
System.out.println(result);
//localRoot.displayNode();
preOrder(localRoot.rightChild,result);
return;
}else{
//System.out.println("trenutni root je" );
//localRoot.displayNode();
result=result + localRoot.data;
// StringBuilder stringBuilder1 = new StringBuilder();
//stringBuilder1.append(result).append(localRoot.data);
System.out.println(result);
preOrder(localRoot.leftChild,result);
//result=result + localRoot.data;
//System.out.print(root.data);
preOrder(localRoot.rightChild,result);
//System.out.print(root.data);
//preOrder(localRoot.rightChild);
return;
}
}
}
}
my problem with it is that with localRoot.DisplayNode() i get the result i want. But when i add the same thing to the String result it adds data, until i get to leaf of the tree(leaf doesnt have left/right child) so it returns to previous recursive call, and goes to right child, here somewhere the leaf(from which we came back) isnt in String anymore. How do i fix this?
String is defined in main method
Related
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Scanner;
import static java.lang.System.in;
import static java.lang.System.out;
/*
*
*
Use a stack to check parentheses, balanced and nesting
* The parentheses are: (), [] and {}
*
* See:
* - UseAStack
*
*/
public class Ex3CheckParen {
public static void main(String[] args) {
new Ex3CheckParen().program();
}
void program() {
// All should be true
out.println(checkParentheses("()"));
out.println(checkParentheses("(()())"));
out.println(!checkParentheses("(()))")); // Unbalanced
out.println(!checkParentheses("((())")); // Unbalanced
out.println(checkParentheses("({})"));
out.println(!checkParentheses("({)}")); // Bad nesting
out.println(checkParentheses("({} [()] ({}))"));
out.println(!checkParentheses("({} [() ({)})")); // Unbalanced and bad nesting
}
// This is interesting because have to return, but what if no match?!?
boolean checkParentheses(String str) {
Deque<Character> stack = new ArrayDeque<>();
String k = "({[";
String s = ")]}";
for (int i = 0; i < str.length(); i++) {
if (k.contains(String.valueOf(str.charAt(i)))) {
stack.push(str.charAt(i));
} else if (s.contains(String.valueOf(str.charAt(i)))) {
if (matching(stack.peek()) == str.charAt(i)) { //ILLEGAL ARGUMENT EXCEPTION HERE
return true;
}
} else {
return false;
}
}
return false;
}
char matching(char ch) {
//char c = must initialize but to what?!
switch (ch) {
case ')':
return '('; // c = '('
case ']':
return '[';
case '}':
return '{';
default:
// return c;
throw new IllegalArgumentException("No match found");
}
}
}
I'm getting an exception error in the if statement containing matching. Unable to figure out the cause.
Maybe something like this?
public class Ex3CheckParen {
public static void main(String[] args) {
new Ex3CheckParen().program();
}
void program() {
// All should be true
out.println(checkParentheses("()"));
out.println(checkParentheses("(()())"));
out.println(!checkParentheses("(()))")); // Unbalanced
out.println(!checkParentheses("((())")); // Unbalanced
out.println(checkParentheses("({})"));
out.println(!checkParentheses("({)}")); // Bad nesting
out.println(checkParentheses("({} [()] ({}))"));
out.println(!checkParentheses("({} [() ({)})")); // Unbalanced and bad nesting
}
// This is interesting because have to return, but what if no match?!?
boolean checkParentheses(String str) {
Deque<Character> stack = new ArrayDeque<>();
String k = "({[";
String s = ")]}";
for (int i = 0; i < str.length(); i++) {
if (k.contains(String.valueOf(str.charAt(i)))) {
stack.push(str.charAt(i));
} else if (s.contains(String.valueOf(str.charAt(i)))) {
if (matching(stack.peek(), str.charAt(i))) {
return true;
}
} else {
return false;
}
}
return false;
}
boolean matching(char ch1, char ch2) {
if ('(' == ch1 && ch2 == ')' || '[' == ch1 && ch2 == ']' || '{' == ch1 && ch2 == '}') {
return true;
}
return false;
}
}
In my opinion by the way, the method checkParentheses(String str) should look more like this:
boolean checkParentheses(String str) {
Deque<Character> stack = new ArrayDeque<>();
String open = "({[";
String close = ")]}";
int length = 0;
for (int i = 0; i < str.length(); i++) {
char currentChar = str.charAt(i);
if (open.contains(String.valueOf(currentChar))) {
stack.push(currentChar);
length++;
} else if (close.contains(String.valueOf(currentChar))) {
if (!stack.isEmpty() && matching(stack.peek(), currentChar)) {
stack.pop();
length--;
}
else {
return false;
}
} else {
return false;
}
}
if (length == 0)
return true;
return false;
}
But it is totally up to you...
I'm a bit new to java, I'm having one error with my Java program that I can't seem to fix, very easy solution I just can't see it haha. How can I fix this? I tried a few things but it adds more errors on top of each other. Thank you all!
import java.io.*;
import java.util.*;
class Node {
public char ch;
public Node leftChild;
public Node rightChild;
Node(char c) {
ch = c;
}
public void displayNode() {
System.out.print(ch);
}
}
class Tree {
public Node root;
public Tree(Node nd) {
root = nd;
}
public void traverse(int traverseType) {
switch (traverseType) {
case 1:
System.out.print(" \n Preorder traversal : ");
preOrder(root);
break;
case 2:
System.out.print(" \n Inorder traversal : ");
inOrder(root);
break;
case 3:
System.out.print(" \n Postorder traversal : ");
postOrder(root);
break;
}
System.out.println();
}
private void preOrder(Node localRoot) {
if (localRoot != null) {
localRoot.displayNode();
preOrder(localRoot.leftChild);
preOrder(localRoot.rightChild);
}
}
private void inOrder(Node localRoot) {
if (localRoot != null) {
inOrder(localRoot.leftChild);
localRoot.displayNode();
inOrder(localRoot.rightChild);
}
}
private void postOrder(Node localRoot) {
if (localRoot != null) {
postOrder(localRoot.leftChild);
postOrder(localRoot.rightChild);
localRoot.displayNode();
}
}
public void displayTree() {
Stack globalStack = new Stack();
globalStack.push(root);
int nBlanks = 32;
boolean isRowEmpty = false;
System.out.println(" ...................................................... ");
while (isRowEmpty == false) {
Stack localStack = new Stack();
isRowEmpty = true;
for (int j = 0; j < nBlanks; j++)
System.out.print(' ');
while (globalStack.isEmpty() == false) {
Node temp = (Node) globalStack.pop();
if (temp != null) {
temp.displayNode();
localStack.push(temp.leftChild);
localStack.push(temp.rightChild);
if (temp.leftChild != null || temp.rightChild != null)
isRowEmpty = false;
} else {
System.out.print("-");
localStack.push(null);
localStack.push(null);
}
for (int j = 0; j < nBlanks * 2 - 1; j++)
System.out.print(' ');
}
System.out.println();
nBlanks / = 2;
while (localStack.isEmpty() == false)
globalStack.push(localStack.pop());
}
System.out.println(" ...................................................... ");
}
}
class BottomUp {
private String inString;
private int strlen;
private Tree[] treeArray;
private Tree aTree;
private int numNodes;
BottomUp(String s) {
inString = s;
strlen = inString.length();
treeArray = new Tree[100];
for (int j = 0; j < strlen; j++) {
char ch = inString.charAt(j);
Node aNode = new Node(ch);
treeArray[j] = new Tree(aNode);
}
}
public Tree getTree() {
return aTree;
}
public void balanced() {
numNodes = strlen;
while (numNodes > 1) {
int i = 0;
int j = 0;
Tree[] tempArray = new Tree[100];
for (j = 0; j < strlen - 1; j++) {
Tree tree1 = treeArray[j];
Tree tree2 = treeArray[j + 1];
Node aNode = new Node('+');
aTree = new Tree(aNode);
aTree.root.leftChild = tree1.root;
aTree.root.rightChild = tree2.root;
tempArray[i++] = aTree;
numNodes--;
j++;
}
if (strlen % 2 == 1) {
Tree tree1 = treeArray[j];
Node aNode = new Node('+');
aTree = new Tree(aNode);
aTree.root.leftChild = tree1.root;
tempArray[i++] = aTree;
}
treeArray = tempArray;
strlen = numNodes;
}
aTree = treeArray[0];
}
}
class BottomUpApp {
public static void main(String[] args) throws IOException {
BottomUp bup;
Tree theTree = null;
int value;
String str;
while (true) {
System.out.print(" Enter first letter of ");
System.out.print(" balanced , show , or traverse : ");
int choice = getChar();
switch (choice) {
case 'b':
System.out.print(" Enter string : ");
str = getString();
bup = new BottomUp(str);
bup.balanced();
theTree = bup.getTree();
break;
case 's':
theTree.displayTree();
break;
case 't':
System.out.print(" Enter type 1, 2 or 3 : ");
value = getInt();
theTree.traverse(value);
break;
default:
System.out.print(" Invalid entry \n ");
}
}
}
public static String getString() throws IOException {
InputStreamReader isr = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(isr);
String s = br.readLine();
return s;
}
public static char getChar() throws IOException {
String s = getString();
return s.charAt(0);
}
public static int getInt() throws IOException {
String s = getString();
return Integer.parseInt(s);
}
}
ERROR CODE
Node.java:112: error: illegal start of expression
nBlanks / = 2 ;
^
1 error
The Java operator /= must be typed without spaces in between, or else it will be parsed as 2 separate operators, / and =, which is a syntax error. Try
nBlanks /= 2 ;
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
im work this assignment and keep getting Exception in thread
"main" java.lang.RuntimeException: Stack Underflow at Stack.pop(Postfix.java:74)
at Postfix.eval(Postfix.java:221)at Postfix.main(Postfix.java:112)
dont know why i look at the stack and write it correct , i cant see problem why it pop when (3*4)/5
import java.io.IOException;
class CharStack
{
private final int STACKSIZE= 80;
private int top;
private char[] items;
public CharStack(){
items = new char[STACKSIZE];
top =-1;
}
public boolean empty() {
if(top==-1){
return true;
}
return false;
}
public char pop() {
if(empty()){
throw new RuntimeException("Stack Underflow");
}
return items[top--];
}
public void push(char symb)
{
if(top == STACKSIZE -1) {
throw new RuntimeException("Stack Overflow");
}
items[++top] =symb;
}
public char peek() {
if(empty()){
throw new RuntimeException("Stack Underflow");
}
return items[top];
}
}
class Stack {
private final int STACKSIZE= 80;
private int top;
private double[] items;
public Stack(){
items = new double[STACKSIZE];
top =-1;
}
public void push(double x)
{
if(top == STACKSIZE -1) {
throw new RuntimeException("Stack Overflow");
}
items[++top] =x;
}
public double pop(){
if(empty()){
System.out.print(top);
throw new RuntimeException("Stack Underflow");
}
return items[top--];
}
public double peek() {
if(empty()){
throw new RuntimeException("Stack Underflow");
}
return items[top];
}
boolean empty()
{
if(top==-1){
return true;
}
return false;
}
}
public class Postfix {
public final static int MAXCOLS = 80;
public static void main(String[] args) throws IOException {
String infix, pfix;
System.out.println("Enter a infix String: ");
infix = readString().trim();
System.out.println("The original infix expr is: " + infix);
pfix = postfix(infix);
System.out.println("The Postfix expr is: " + pfix);
System.out.println("The value is : " + eval(pfix));
} // end main
public static boolean isOperand(char x)
{
if(x == '+')
{
return false;
}
else if(x == '-')
{
return false;
}
else if (x == '*')
{
return false;
}
else if (x == '/')
{
return false;
}
else if ( x== '$')
{
return false;
}
return true;
}
public static int operPrecedence(char oper)
{
if(oper == '+'||oper == '-' )
{
return 1;
}
else if (oper == '*' || oper == '/')
{
return 2;
}
else if (oper == '$')
{
return 3;
}
return 0;
}
public static boolean precedence(char top, char symb)
{
if ((top != '('||top != ')')&&symb == '(')
{
return false;
}
if (top == '(' && (symb != '('||symb != ')') )
{
return false;
}
else if((top != '('||top != ')')&&symb ==')' )
{
return true;
}
int opcode1, opcode2;
opcode1 =operPrecedence(top) ;
opcode2 =operPrecedence(symb) ;
if(opcode1>=opcode2){
return true;
}
return false;
}
public static String readString() throws IOException {
char[] charArray = new char[80];
int position = 0;
char c;
while ((c = (char) System.in.read()) != '\n') {
charArray[position++] = c;
}
return String.copyValueOf(charArray, 0, position); // turns a character array into a string, starting between zero and position-1
}// end read string
public static double eval(String infix) {
char c;
int position;
double opnd1, opnd2, value;
Stack opndstk = new Stack();
for (position = 0; position < infix.length(); position++) {
c = infix.charAt(position);
if (Character.isDigit(c)) // operand-convert the character represent of
// the digit into double and push it into the
// stack
{
opndstk.push((double) Character.digit(c, 10));
} else {
// operator
opnd2 = opndstk.pop();
opnd1 = opndstk.pop();
value = oper(c, opnd1, opnd2);
opndstk.push(value);
} // else
} // end for
return opndstk.pop();
}// end eval
public static String postfix(String infix) {
int position, outpos = 0;
char symb;
char[] postr = new char[MAXCOLS];
CharStack opstk = new CharStack();
for (position = 0; position < infix.length(); position++) {
symb = infix.charAt(position);
if (isOperand(symb)) {
postr[outpos++] = symb;
} else {
while (!opstk.empty() && precedence(opstk.peek(), symb)) {
postr[outpos++] = opstk.pop();
} // end while
if (symb != ')') {
opstk.push(symb);
} else {
opstk.pop();
}
} // end else
} // end for
while (!opstk.empty()) {
postr[outpos++] = opstk.pop();
}
return String.copyValueOf(postr, 0, outpos);
}// end pos
public static double oper(char symb, double op1, double op2) {
double value = 0;
switch (symb) {
case '+':
value = op1 + op2;
break;
case '-':
value = op1 - op2;
break;
case '*':
value = op1 * op2;
break;
case '/':
value = op1 / op2;
break;
case '$':
value = Math.pow(op1, op2);
break;
default:
throw new RuntimeException("illegal operator: " + symb);
}// end switch
return value;
}// end oper
}
At least part of the problem you're having is your isOperand method. The characters ( and ) are not operands, however, when they are passed to this method, it would return true. For a quick test, I added the following lines to the end of the method:
else if (x == '(')
{
return true;
}
else if (x == ')')
{
return true;
}
And your example input, (3*4)/5) runs successfully. However, this breaks your postfix output, as it leaves the brackets out of the postfix version and instead prints 34*5/, which I am guessing you don't want.
Then, I looked at your eval method, which is where the problem is coming from, according to the error message I'm receiving:
Exception in thread "main" java.lang.RuntimeException: Stack Underflow
at Stack.pop(Postfix.java:74)
at Postfix.eval(Postfix.java:221)
at Postfix.main(Postfix.java:112)
Note the line Postfix.java:221, which indicates the line that called the method which created the error. If you output your character c right before that line is called, you'll notice that c is the ( character, which means your eval method is recognizing ( as an operator, and is attempting to pop two operands after it, causing your underflow.
All of this is fairly simple to determine with some System.out.println() calls, and looking at your error. I'll leave the actual fixing to you, but at least you've hopefully got a direction to head in now.
I'm implementing the Servlet URL pattern matching follow the Servlet Specification. My matching method:
public static boolean match(String pattern, String str, boolean isCaseSensitive) {
char[] patArr = pattern.toCharArray();
char[] strArr = str.toCharArray();
int patIdxStart = 0;
int patIdxEnd = patArr.length - 1;
int strIdxStart = 0;
int strIdxEnd = strArr.length - 1;
boolean containsStar = false;
for (int i = 0; i < patArr.length; i++) {
if (patArr[i] != '*') {
continue;
}
containsStar = true;
break;
}
if (!containsStar) {
if (patIdxEnd != strIdxEnd) {
return false;
}
for (int i = 0; i <= patIdxEnd; i++) {
char ch = patArr[i];
if (ch == '?')
continue;
if ((isCaseSensitive) && (ch != strArr[i])) {
return false;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[i]))) {
return false;
}
}
return true;
}
if (patIdxEnd == 0) {
return true;
}
char ch;
while (((ch = patArr[patIdxStart]) != '*')
&& (strIdxStart <= strIdxEnd)) {
if (ch != '?') {
if ((isCaseSensitive) && (ch != strArr[strIdxStart])) {
return false;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[strIdxStart]))) {
return false;
}
}
patIdxStart++;
strIdxStart++;
}
if (strIdxStart > strIdxEnd) {
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
while (((ch = patArr[patIdxEnd]) != '*') && (strIdxStart <= strIdxEnd)) {
if (ch != '?') {
if ((isCaseSensitive) && (ch != strArr[strIdxEnd])) {
return false;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[strIdxEnd]))) {
return false;
}
}
patIdxEnd--;
strIdxEnd--;
}
if (strIdxStart > strIdxEnd) {
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
while ((patIdxStart != patIdxEnd) && (strIdxStart <= strIdxEnd)) {
int patIdxTmp = -1;
for (int i = patIdxStart + 1; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
continue;
}
patIdxTmp = i;
break;
}
if (patIdxTmp == patIdxStart + 1) {
patIdxStart++;
continue;
}
int patLength = patIdxTmp - patIdxStart - 1;
int strLength = strIdxEnd - strIdxStart + 1;
int foundIdx = -1;
for (int i = 0; i <= strLength - patLength; i++) {
int j = 0;
while (true)
if (j < patLength) {
ch = patArr[(patIdxStart + j + 1)];
if (ch != '?') {
if ((isCaseSensitive)
&& (ch != strArr[(strIdxStart + i + j)])) {
break;
}
if ((!isCaseSensitive)
&& (Character.toUpperCase(ch) != Character
.toUpperCase(strArr[(strIdxStart
+ i + j)])))
break;
} else {
j++;
continue;
}
} else {
foundIdx = strIdxStart + i;
break;
}
}
if (foundIdx == -1) {
return false;
}
patIdxStart = patIdxTmp;
strIdxStart = foundIdx + patLength;
}
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
But when I test with case below:
String pattern = "*.a*";
String path = "/index.abc";
String matches = match(pattern, path, true) ? "matches" : "unmatches";
System.out.println(path + " " + matches + " " + pattern);
The test case runs forever and cannot stop. I have 2 questions:
Is pattern "*.a*" valid with Servlet URL pattern matching spec?
How to fix this error to break the infinite loop?
Here is my Java Servlet Specification 3.1 (April 2013) Mapping Requests to Servlets implementation.
/**
* Java Servlet Specification 3.1 (April 2013)
* Mapping Requests to Servlets (Chapter 12) implementation.
*
* This class is thread safe.
*/
public class ServletMappingMatcher {
private final String[] patterns;
private final String[] welcomePages;
public ServletMappingMatcher(String... patterns) {
this(patterns, new String[0]);
}
public ServletMappingMatcher(String[] patterns, String[] welcomePages) {
this.patterns = patterns;
this.welcomePages = welcomePages;
}
public String getPatternForPath(String path) {
for (String pattern : patterns) {
if (matches(pattern, path)) {
return pattern;
}
}
return null;
}
private boolean matches(String pattern, String path) {
if (isPathMapping(pattern)) {
return pathMatches(pattern, path);
} else if (isExtensionPattern(pattern)) {
return extensionMatches(pattern, path);
} else if (isApplicationContextRoot(pattern)) {
return matchesApplicationContextRoot(path);
} else if (isDefaultServlet(pattern)) {
return matchesDefaultServlet(path);
}
return strictlyMatches(pattern, path);
}
private boolean isPathMapping(String pattern) {
return pattern.startsWith("/") && pattern.endsWith("/*");
}
private boolean isExtensionPattern(String pattern) {
return pattern.startsWith("*.");
}
private boolean isApplicationContextRoot(String pattern) {
return pattern.isEmpty();
}
private boolean isDefaultServlet(String pattern) {
return pattern.equals("/");
}
private boolean pathMatches(String pattern, String path) {
return path.startsWith(pattern.substring(0, pattern.length() - 1)) ||
path.equals(pattern.substring(0, pattern.length() - 2));
}
private boolean extensionMatches(String pattern, String path) {
return path.endsWith(pattern.substring(1));
}
private boolean matchesApplicationContextRoot(String path) {
return path.equals("/");
}
private boolean strictlyMatches(String pattern, String path) {
return path.equals(pattern);
}
private boolean matchesDefaultServlet(String path) {
if (path.endsWith("/")) {
return true;
}
for (String welcomePage : welcomePages) {
if (path.endsWith("/" + welcomePage)) {
return true;
}
}
return false;
}
}
And JUnit tests:
import org.junit.Assert;
import org.junit.Test;
public class ServletMappingMatcherTest {
#Test
public void testsFromSpec() {
final String servlet1Pattern = "/foo/bar/*";
final String servlet2Pattern = "/baz/*";
final String servlet3Pattern = "/catalog";
final String servlet4Pattern = "*.bop";
final String defaultServlet = "/";
final String[] patterns = {servlet1Pattern, servlet2Pattern, servlet3Pattern, servlet4Pattern, defaultServlet};
final String[] welcomePages = {"index.html"};
final ServletMappingMatcher matcher = new ServletMappingMatcher(patterns, welcomePages);
Assert.assertEquals(servlet1Pattern, matcher.getPatternForPath("/foo/bar/index.html"));
Assert.assertEquals(servlet1Pattern, matcher.getPatternForPath("/foo/bar/index.bop"));
Assert.assertEquals(servlet2Pattern, matcher.getPatternForPath("/baz"));
Assert.assertEquals(servlet2Pattern, matcher.getPatternForPath("/baz/index.html"));
Assert.assertEquals(servlet3Pattern, matcher.getPatternForPath("/catalog"));
Assert.assertEquals(defaultServlet, matcher.getPatternForPath("/catalog/index.html"));
Assert.assertEquals(servlet4Pattern, matcher.getPatternForPath("/catalog/rececar.bop"));
Assert.assertEquals(servlet4Pattern, matcher.getPatternForPath("/index.bop"));
}
}
I fixed it, in the while(true) loop add below line to break the loop:
[...]
while(true) {
if (ch != '?') {
if(...) {
//...
break;
}
if(...) {
//...
break;
}
j++; // Add this line to avoid infinite loop
}
}
The calculator is now almost working. It now gives me the same answer for every equation it reads in?
the output ends up as:
49+62*61-36
15.666666666666668
4/64
15.666666666666668
(53+26)
15.666666666666668
0*72
15.666666666666668
21-85+75-85
15.666666666666668
90*76-50+67
15.666666666666668
46*89-15
15.666666666666668
34/83-38
15.666666666666668
20/76/14+92-15
15.666666666666668
5*10/3-1
15.666666666666668
Instead of having the answer for each equation there?
Have i missed something out in my methods?
Thanks
All code is shown below. Any help will be much appreciated.
Stack class:
import java.util.Iterator;
import java.util.NoSuchElementException;
public class myStack<Item> implements Iterable<Item> {
private int N; // size of the stack
private Node first; // top of stack
private class Node {
private Item item;
private Node next;
}
/**
* Create an empty stack.
*/
public myStack() {
first = null;
N = 0;
assert check();
}
public boolean isEmpty() {
return first == null;
}
public int size() {
return N;
}
public void push(Item item) {
Node oldfirst = first;
first = new Node();
first.item = item;
first.next = oldfirst;
N++;
assert check();
}
public Item pop() {
if (isEmpty())
throw new NoSuchElementException("Stack underflow");
Item item = first.item; // save item to return
first = first.next; // delete first node
N--;
assert check();
return item; // return the saved item
}
public Item peek() {
if (isEmpty())
throw new NoSuchElementException("Stack underflow");
return first.item;
}
public String toString() {
StringBuilder s = new StringBuilder();
for (Item item : this)
s.append(item + " ");
return s.toString();
}
// check internal invariants
private boolean check() {
if (N == 0) {
if (first != null)
return false;
} else if (N == 1) {
if (first == null)
return false;
if (first.next != null)
return false;
} else {
if (first.next == null)
return false;
}
// check internal consistency of instance variable N
int numberOfNodes = 0;
for (Node x = first; x != null; x = x.next) {
numberOfNodes++;
}
if (numberOfNodes != N)
return false;
return true;
}
public Object[] toArray(String[] elementData) {
return (Object[]) elementData.clone();
}
public Iterator<Item> iterator() {
return new ListIterator();
}
// did not implement remove as it was not needed
private class ListIterator implements Iterator<Item> {
private Node current = first;
public boolean hasNext() {
return current != null;
}
public void remove() {
throw new UnsupportedOperationException();
}
public Item next() {
if (!hasNext())
throw new NoSuchElementException();
Item item = current.item;
current = current.next;
return item;
}
}
}
Array list class
import java.util.Arrays;
public class myArrayList<Item>{
private Object[] myStore;
private int actSize = 0;
public myArrayList() {
myStore = new Object[100];
}
public Object get(int index) {
if (index < actSize) {
return myStore[index];
} else {
throw new ArrayIndexOutOfBoundsException();
}
}
public void add(Object obj) {
if (myStore.length - actSize <= 0) {
increaseListSize();
}
myStore[actSize++] = obj;
}
public Object remove(int index) {
if (index < actSize) {
Object obj = myStore[index];
myStore[index] = null;
int tmp = index;
while (tmp < actSize) {
myStore[tmp] = myStore[tmp + 1];
myStore[tmp + 1] = null;
tmp++;
}
actSize--;
return obj;
} else {
throw new ArrayIndexOutOfBoundsException();
}
}
public int size() {
return actSize;
}
private void increaseListSize() {
myStore = Arrays.copyOf(myStore, myStore.length * 2);
}
#SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
if (a.length < size())
// Make a new array of a's runtime type, but my contents:
return (T[]) Arrays.copyOf(myStore, size(), a.getClass());
System.arraycopy(myStore, 0, a, 0, size());
if (a.length > size())
a[size()] = null;
return a;
}
}
The TestClass for equation handling
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.StringTokenizer;
public class TestClass {
private static final int LEFT_ASSOC = 0;
private static final int RIGHT_ASSOC = 1;
static String OPERATORS1 = "+-*/()";
// Operators
private static final Map<String, int[]> OPERATORS = new HashMap<String, int[]>();
static {
// Map<"token", []{precedence, associativity}>
OPERATORS.put("+", new int[] { 0, LEFT_ASSOC });
OPERATORS.put("-", new int[] { 0, LEFT_ASSOC });
OPERATORS.put("*", new int[] { 5, LEFT_ASSOC });
OPERATORS.put("/", new int[] { 5, LEFT_ASSOC });
OPERATORS.put("(", new int[] {1, LEFT_ASSOC});
OPERATORS.put(")", new int[] {1, LEFT_ASSOC});
}
private static boolean isOperator(String token) {
return OPERATORS.containsKey(token);
}
// Test associativity of operator token
private static boolean isAssociative(String token, int type) {
if (!isOperator(token)) {
throw new IllegalArgumentException("Invalid token: " + token);
}
if (OPERATORS.get(token)[1] == type) {
return true;
}
return false;
}
// Compare precedence of operators.
private static final int cmpPrecedence(String token1, String token2) {
if (!isOperator(token1) || !isOperator(token2)) {
throw new IllegalArgumentException("Invalid tokens: " + token1
+ " " + token2);
}
return OPERATORS.get(token1)[0] - OPERATORS.get(token2)[0];
}
public static String[] infixToRPN(String[] inputTokens) {
myArrayList<String> out = new myArrayList<String>();
myStack<String> stack = new myStack<String>();
// For each token
for (String token : inputTokens) {
StringTokenizer tokens = new StringTokenizer(token,OPERATORS1,true);
while (tokens.hasMoreTokens()) {
token = tokens.nextToken();
// If token is an operator
if (isOperator(token)) {
// While stack not empty AND stack top element
// is an operator
while (!stack.isEmpty() && isOperator(stack.peek())) {
if ((isAssociative(token, LEFT_ASSOC) && cmpPrecedence(
token, stack.peek()) <= 0)
|| (isAssociative(token, RIGHT_ASSOC) && cmpPrecedence(
token, stack.peek()) < 0)) {
out.add(stack.pop());
continue;
}
break;
}
// Push the new operator on the stack
stack.push(token);
}
// If token is a left bracket '('
else if (token.equals("(")) {
stack.push(token);
}
// If token is a right bracket ')'
else if (token.equals(")")) {
while (!stack.isEmpty() && !stack.peek().equals("(")) {
out.add(stack.pop());
}
stack.pop();
}
// If token is a number
else {
out.add(token);
}
}
while (!stack.isEmpty()) {
out.add(stack.pop());
}
}
String[] output = new String[out.size()];
return out.toArray(output);
}
public static double RPNtoDouble(String[] tokens) {
myStack<String> stack = new myStack<String>();
// For each token
for (String token : tokens) {
//System.out.println( "Working this token: " + token );
// If the token is a value push it onto the stack
if (!isOperator(token)) {
stack.push(token);
} else {
// Token is an operator: pop top two entries
Double d2 = Double.valueOf(stack.pop());
Double d1 = Double.valueOf(stack.pop());
// Get the result
Double result = token.compareTo("+") == 0 ? d1 + d2 : token
.compareTo("-") == 0 ? d1 - d2
: token.compareTo("*") == 0 ? d1 * d2 : d1 / d2;
// Push result onto stack
stack.push(String.valueOf(result));
}
}
return Double.valueOf(stack.pop());
}
static public void main(String[] args) throws IOException {
File file = new File("testEquations.txt");
String[] lines = new String[1];
try {
FileReader reader = new FileReader(file);
#SuppressWarnings("resource")
BufferedReader buffReader = new BufferedReader(reader);
int x = 0;
String s;
while ((s = buffReader.readLine()) != null) {
lines[x] = s;
x++;
}
} catch (IOException e) {
System.exit(0);
}
// test printing string array
for (String s : lines) {
System.out.println("" + s);
String[] output =infixToRPN(lines);
System.out.println(RPNtoDouble(output));
}
}
}
Your problem is here:
String[] lines = new String[1];
try {
FileReader reader = new FileReader(file);
#SuppressWarnings("resource")
BufferedReader buffReader = new BufferedReader(reader);
int x = 0;
String s;
while ((s = buffReader.readLine()) != null) {
lines[x] = s;
x++;
}
...
you define array of string with a size = 1 but you don't check inside the loop if x is getting out of the borders of this array.
Do somethink like this:
int Size = // define the size..;
String[] lines = new String[Size];
...
while (x < Size && (s = buffReader.readLine()) != null)) {
lines[x] = s;
x++;
}
when your x becames bigger then Size, x < Size will evaluate false, thus getting out of the loop.
About one of the error you are getting ArrayIndexOutOfBoundsException:
Thrown to indicate that an array has been accessed with an illegal
index. The index is either negative or greater than or equal to the
size of the array. (source)
The other error NoSuchElementException :
Thrown by the nextElement method of an Enumeration to indicate that
there are no more elements in the enumeration (source).
Another problem is here:
// test printing string array
for (String s : lines)
{
System.out.println("" + s);
String[] output =infixToRPN(lines);
System.out.println(RPNtoDouble(output));
}
You have to pass s, and not lines into method infixToRPN, thats why you are getting the same output, because you are giving the same input.
Remember that infixToRPN receives a String [] not a string like 's', but this I leave to you to find a workaround.