Postfix Evaluation using Stacks - java

I'm trying to write a method that solves a postfix equation. For ex.
1 2 + 3 *
This would = 9
As of now I'm getting a ArrayoutofboundsException. I think the problem is around my if(statement) in my postFixEvaluation Method.
The first part of code is the method I was talking about where I need the help.
After that is the rest of my code. Not sure if yall need to read that or not.
public int PostfixEvaluate(String e) {
String Operator = "";
int number1;
int number2;
int result = 0;
char c;
number1 = 0;
number2 = 0;
for (int j = 0; j < e.length(); j++) {
c = e.charAt(j);
if (c == (Integer) (number1)) {
s.push(c);
} else {
number1 = s.pop();
number2 = s.pop();
switch (c) {
case '+':
result = number1 + number2;
break;
case '-':
result = number1 - number2;
break;
case '*':
result = number1 * number2;
break;
case '/':
result = number1 / number2;
break;
case '%':
result = number1 % number2;
break;
}
}
}
return result;
}
public static void main(String[] args) {
Stacked st = new Stacked(100);
String y = new String("(z * j)/(b * 8) ^2");
String x = new String("10 3 + 9 *");
TestingClass clas = new TestingClass(st);
clas.test(y);
//System.out.println(stacks.test(y));
clas.PostfixEvaluate(x);
}
Here's the rest of code that may be relevant:
public class Stacked {
int top;
char stack[];
int maxLen;
public Stacked(int max) {
top = 0;
maxLen = max;
stack = new char[maxLen];
}
public void push(int result) {
top++;
stack[top] = (char) result;
}
public int pop() {
int x;
x = stack[top];
//top = top - 1;
top--;
return x;
}
public boolean isStackEmpty() {
if (top == 0) {
System.out.println("Stack is empty " + "Equation Good");
return true;
} else
System.out.println("Equation is No good");
return false;
}
public void reset() {
top = -1;
}
public void showStack() {
System.out.println(" ");
System.out.println("Stack Contents...");
for (int j = top; j > -1; j--) {
System.out.println(stack[j]);
}
System.out.println(" ");
}
public void showStack0toTop() {
System.out.println(" ");
System.out.println("Stack Contents...");
for (int j = 0; j >= top; j++) {
System.out.println(stack[j]);
}
System.out.println(" ");
}
}

You need to push the result of the operation back on to the stack. Then at the end (when at the end of the expression string), pop the stack and return the value.
// excerpted, with odd bracket indentions unchanged.
for(int j = 0; j < e.length(); j++){
c = e.charAt(j);
if (c == (Integer)(number1)) {
s.push(c); }
else {
number1 = s.pop();
number2 = s.pop();
switch(c) {
case '+':
result = number1 + number2;
break;
case '-':
result = number1 - number2;
break;
case '*':
result = number1 * number2;
break;
case '/':
result = number1 / number2;
break;
case '%':
result = number1 % number2;
break;
}
s.push(result); // <=== push here
}
}
}
return s.pop(); // <==== pop here

Related

Converting infix to postfix using java

this is my last resort. Will someone help me with my program?
The program is to convert infix to postfix, the issue is it won't give me an answer with decimal. I know i need to use double, but i don't know where to insert it.
here is my code
import java.util.*;
class Stack
{
int capacity = 10;
char arr []=new char[capacity];
int top = -1;
boolean isEmpty()
{
if(top==-1){
return true;
}
else {
return false;
}
}
void push(char c)
{
top++;
if (top <= capacity-1)
{
arr[top]= c;
}
else if (top > capacity-1)
{
System.out.println("Overflow"); //Stack is ful
System.exit(0);
}
}
char pop ()
{
if (isEmpty()==true){
System.out.print("Underflow");
System.exit(0);
}
return arr[top--];
}
char peek()
{
return arr[top];
}
}
public class Operations
{
static Stack s = new Stack ();
static int precedence(char c){
switch (c){
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
return 3;
}
return -1;
}
public static String Conversion(String val){
String result = "";
for (int i = 0; i <val.length() ; i++) {
char c = val.charAt(i);
if(precedence(c)>0){
while(s.isEmpty()==false && precedence(s.peek())>=precedence(c)){
result += s.pop();
}
s.push(c);
}else if(c==')'){
char x = s.pop();
while(x!='('){
result += x;
x = s.pop();
}
}else if(c=='('){
s.push(c);
}else{
result += c;
}
if (i+1 >= val.length() || !Character.isDigit(val.charAt(i+1)))
result += ' ';
}
while (!s.isEmpty())
result = result + s.pop();
return result;
}
public static double Result(String Postfix)
{
for(int i=0; i < Postfix.length(); i++)
{
char ch = Postfix.charAt(i);
//check if it is a space (separator)
if(ch==' ')
continue;
if (Character.isDigit(ch)){
double num = 0;
while(Character.isDigit(ch)) {
num = num*10 + (ch-'0');
i++;
ch = Postfix.charAt(i);
}
i--;
s.push((char)(num));
}
else
{
double value1 = s.pop();
double value2 = s.pop();
switch(ch) //evaluating the expression
{
case '+':
s.push((char)(value2 + value1));
break;
case '-':
s.push((char)(value2 - value1));
break;
case '*':
s.push((char)(value2*value1));
break;
case '/':
if(value1==0){
System.out.print("Cannot divide by zero");
System.exit(0);
}
else
s.push((char)(value2/value1));
break;
}
}
}
return s.pop();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter an infix expression: ");
String val = sc.next();
String Postfix = Conversion(val);
System.out.println("Postfix expression is: "+(Postfix.replaceAll("\\s+","")));
System.out.println("Result of the evaluation is: " + Result(Postfix));
}
}
i am not confident with the codes if it's correct. but any enlighten is welcome.
and perhaps can u help me with the loop? so i won't start to re-run the program everytime i input from the keyboard, big thanks seniors

Portion of code not running

Part of my java code is not running. I am fairly new to java and have been working out some new environment changes. My class was told to build a windchill temperature calculator. My main issue is that my code works up to the for (ws = wsp; ws <= c; ws += 0.5) then stops.
import java.util.*;
class Assign1
{
public static void main(String args[])
{
Menu user = new Menu();
Menu.mainmenu();
user.acceptSelection();
}
}
class Menu
{
public static void mainmenu()
{
System.out.println("Temperature Analysis MENU");
System.out.println("1.W)ind Chill Temperature");
System.out.println("0.E)xit");
System.out.println("Enter Selection:");
}
public void acceptSelection()
{
Scanner stdin = new Scanner(System.in);
String selection = stdin.nextLine();
char choice = selection.charAt(0);
switch(choice)
{
case 'W':
case 'w':
case '1':
processing.process(); break;
case 'E':
case 'e':
case '0':
System.out.println("E"); break;
}
}
}
class processing
{
public static void process()
{
Scanner stdin = new Scanner(System.in);
System.out.println("\n\n\n\n\n\n\n");
System.out.print("Please enter START air temp in celsius (decimal) MUST be BELOW 9: ");
double sa = stdin.nextDouble();
System.out.print("Please enter END air temp in celsius (decimal) MUST be BELOW 9: ");
double ea = stdin.nextDouble();
System.out.print("Please enter wind speed (decimal) FROM 8km/h to: ");
double w = stdin.nextDouble();
System.out.println("\n==================================================================\n");
calculation(sa, ea, w);
}
public static void calculation(double a, double b, double c)
{
double wsp = 8.0;
double airTemp;
double ws;
int size = 150;
double[] wChill = new double[size];
int count = 0;
System.out.print(" " + a);
while(a <= b)
{
System.out.print(" " + a);
a +=5;
count++;
}
System.out.print(" " + b);
int count2 = 0;
while(wsp <= c)
{
count2++;
wsp += 0.5;
}
double[][] chart = new double[count2][count];
int i = 0, j = 0, k = 0;
This is where it stops working. I cannot get it to print my loop out. Any help in fixing my problem would be appreciated as well as notes to my code as i am trying to improve. I am using JGrasp if it helps.
for (ws = wsp; ws <= c; ws += 0.5)
{
System.out.println(ws + " ");
for (airTemp = a; airTemp <= b; airTemp += 5.0)
{
if ((ws + 0.5) > c)
{
System.out.printf( "%2d %2d", c , chart[k][i]);
}
else
{
wChill[i] = (13.12 + (0.6215*airTemp)+(-11.37*Math.pow(ws, 0.16))+(0.3965*airTemp*Math.pow(ws, 0.16)));
chart[k][i] = wChill[i];
System.out.print(chart[k][i] + " ");
}
i++;
}
k++;
}
}
}
According to you code you have a while loop
while(wsp <= c) {...}
then you have a for loop
for (ws = wsp; ws <= c; ws += 0.5)
so as you can see ws is assigned the value of wsp which has in the while already exceeded the value of c

Why do I get a "String index out of range" error when I run this program?

I am creating a program that converts roman numeral input to it's integer value and every time I run the program I get an error that says,
"Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: 1
at java.lang.String.charAt(String.java:646)
at romannumeralconverter.RomanNumeralConverter.convert(RomanNumeralConverter.java:20)
at romannumeralconverter.RomanNumeralConverter.romanInput(RomanNumeralConverter.java:68)
at romannumeralconverter.RomanNumeralConverter.printValue(RomanNumeralConverter.java:72)
at romannumeralconverter.RomanNumeralConverter.main(RomanNumeralConverter.java:77)
Java Result: 1"
Now I am new to programming so I don't know what this means exactly. I am guessing my conversion algorithm is wrong in which the roman numeral entered is not read by the loop. Here is what I have:
public class RomanNumeralConverter {
public String getUserInput() {
Scanner numberInput = new Scanner (System.in);
System.out.print("Enter a roman numeral in uppercase: ");
String userInput = numberInput.next();
numberInput.close();
return userInput;
}
public int convert (String userInput) {
int result = 0;
int subtractamount = 0;
int x = userInput.length();
while(x != 0) {
char romanConvert = userInput.charAt(x);
if(x >= 1) {
if(convertChar(romanConvert) >= convertChar(userInput.charAt(x - 1))) {
subtractamount += convertChar(userInput.charAt(x - 1));
}
}
result += convertChar(romanConvert);
x--;
}
result -= subtractamount;
return result;
}
public static char convertChar(char value) {
char result;
switch (value) {
case 'I':
result = 1;
break;
case 'V':
result = 5;
break;
case 'X':
result = 10;
break;
case 'L':
result = 50;
break;
case 'C':
result = 100;
break;
case 'D':
result = 500;
break;
case 'M':
result = 1000;
break;
default:
System.out.println("Invalid character!");
result = 0;
break;
}
return result;
}
public int romanInput() {
return convert(getUserInput());
}
public void printValue() {
System.out.println(romanInput());
}
public static void main (String[] args) {
new RomanNumeralConverter().printValue();
}
}
If my algorithm is wrong, does anyone know how to fix it?
change userInput.charAt(x); to userInput.charAt(x - 1);
charAt starts with index 0 to length -1
or int x = userInput.length() - 1;
#nd issue, everything coming out as 0
You are actually using uppercase characters in switch statement.
so just add below statement,in the starting of your function convert(String userInput)
userInput = userInput.toUpperCase(); // converts user input to uppercase , even if its is already or not.
code
public int convert(String userInput) {
userInput = userInput.toUpperCase();
int result = 0;
int subtractamount = 0;
int x = userInput.length() - 1;
while (x != 0) {
char romanConvert = userInput.charAt(x);
if (x >= 1) {
if (convertChar(romanConvert) >= convertChar(userInput.charAt(x - 1))) {
subtractamount += convertChar(userInput.charAt(x - 1));
}
}
result += convertChar(romanConvert);
x--;
}
result -= subtractamount;
return result;
}
output
Enter a roman numeral in uppercase: adig
Invalid character!
Invalid character!
Invalid character!
Invalid character!
501
You should start with
int x = userInput.length() - 1;
The last character in a string is at the index - (length-of-string - 1), not length-of-string.

Command Line Calulator, Java

Input from the Java commandline: "4 + 6 + 5 - 5".
Wanted outcome: "is 10".
Actual outcome: "is 5".
class Calculator
{
int v_in1, v_in2, v_in3, v_in4, v_answer, result;
String v_sign1, v_sign2, v_sign3;
public Calculator()
{
}
public void count(String[] args)
{
for(int i = 0; i < args.length; i++)
{
//System.out.print(args[i]+ " ");
if(i == 0 || i % 2 == 0)
{
v_in1 = Integer.parseInt(args[i]);
//System.out.print(v_in1 + " ");
}
switch(args[i])
{
case "+": {
v_answer += v_in1;
break;
}
case "-": {
v_answer -= v_in1;
break;
}
}
}
System.out.print("is " + v_answer);
}
}
There might be some additional problems e.g too many variable declared etc, but what I'm concerned about it the for- if- switch part, I'm unable to pin- point the problem.
Thank you :)
The problem is that you are applying the operation to the previous number, not to the next to come. Instead you should memorize the operator and update the result when you see a number, e.g. like this:
int sign = +1, result = 0;
for (String arg : args) {
switch (arg) {
case "+":
sign = +1;
break;
case "-":
sign = -1;
break;
default:
result += sign * Integer.parseInt(arg);
}
}
This is happening because your last integer wont be taken into account as it is just stored in v_in1, but since there is no +,- so it doesnt get added or subtracted. Try this:
for(int i = 0; i < args.length; i++)
{
//System.out.print(args[i]+ " ");
if(i == 0 || i % 2 == 0)
{
v_in1 = Integer.parseInt(args[i]);
//System.out.print(v_in1 + " ");
}
switch(args[i])
{
case "+":
{
v_answer = v_in1 + Integer.parseInt(args[i+1]) + v_answer;
i++;
break;
}
case "-":
{
v_answer = v_in1 - Integer.parseInt(args[i+1]) + v_answer;
i++;
break;
}
}
}
I do not know all requirements for this task, but I recommend to convert the whole expression to postfix notation, then parse it using stack to evaluate the result.
I took a look at your method, and I recommend you simplify your code (something like this for long count(String[] args))
long result = 0; // Note, this shadows your Object's result. I'm not sure why you
// had hard-coded fields like that. I don't think you need them.
// Also, this returns a long.
boolean negative = false;
for (String arg : args) {
String oper = arg.trim();
if (oper.equals("+")) { // Is it a plus sign?
negative = false;
} else if (oper.equals("-")) { // Is it a minus sign?
negative = !negative; // - a negative value is addition
} else {
try {
int i = Integer.parseInt(oper); // Parse the integer
if (negative) {
i = -i;
negative = false;
}
result += i; // add the result
} catch (NumberFormatException nfe) {
System.err.println(oper + " is not +, - or a number");
}
}
}
return result;
This is what worked in the exercise.
class Calculator
{
int v_answer = 0;
int v_in1 = 0;
public Calculator()
{
}
public void count(String args[])
{
System.out.println();
System.out.print("Result of the calculation ");
for(int i = 0; i < args.length; i++)
{
System.out.print(args[i]+ " ");
if(i % 2 == 0)
{
v_in1 = Integer.parseInt(args[i]);
}
if(i == 0)
{
v_answer += Integer.parseInt(args[0]);
}
if(args[i].equals("+"))
{
v_answer += Integer.parseInt(args[i+1]);
}
else if(args[i].equals("-"))
{
v_answer -= Integer.parseInt(args[i+1]);
}
}
System.out.print("is " + v_answer);
System.out.println();
}
}

Implementing Arithmetic Right Shift for Booth's Algorithm

I was trying to implement Booth's algorithm using Java, but the arithmetic right shift function(rightShift()) is being ignored in my multiply() function. Is it because I have used a String for the product variable? Here's my code:-
import java.util.Scanner;
class BoothsAlgorithm{
static String appendZeros(int n){
String result = "";
for(int i = 0; i < n; i++) result += "0";
return result;
}
static String rightShift(String str){
String result = "";
for(int i = 0; i < str.length(); i++){
if(i == 0) result += str.charAt(i);
else result += str.charAt(i-1);
}
return result;
}
static String add(String a, String b){
String result = "";
char carry = '0';
for(int i = a.length()-1; i >= 0; i--){
String condition = "" + a.charAt(i) + b.charAt(i) + carry;
switch(condition){
case "000": result = "0" + result; break;
case "001": result = "1" + result; carry = '0'; break;
case "010": result = "1" + result; break;
case "011": result = "0" + result; break;
case "100": result = "1" + result; break;
case "101": result = "0" + result; break;
case "110": result = "0" + result; carry = '1'; break;
case "111": result = "1" + result; break;
}
}
return result;
}
static String multiply(int a, int b){
String op1 = Integer.toBinaryString(a);
String op2 = Integer.toBinaryString(b);
String negop2 = Integer.toBinaryString(-b);
char prev = '0';
String product = appendZeros(64-op1.length())+op1;
for(int i = 0; i < 32; i++){
if(i > 0) prev = product.charAt(63);
if(product.charAt(63)=='0' && prev == '1'){
String temp = appendZeros(32-op2.length()) + op2 + appendZeros(32);
product = add(product, temp);
}
if(product.charAt(63)=='1' && prev == '0'){
String temp = appendZeros(32-negop2.length()) + negop2 + appendZeros(32);
product = add(product, temp);
}
rightShift(product);
}
return product.substring(32);
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
System.out.print("Enter the first number: ");
int operand1 = sc.nextInt();
System.out.print("Enter the second number: ");
int operand2 = sc.nextInt();
System.out.println("The multiplication is "+multiply(operand1, operand2));
}
}
You need product = rightShift(product); or similar. rightShift returns a new String containing its result. It does not, and cannot, change the String referenced by product in the caller.

Categories

Resources