RPN stacking method not working with converted string arrays - java

I'm trying to make a program that processes a line of rpn expression through a stack method. The input is a string array that is converted from a string input.
String[] collect = "8 6 + 2 /"; //the
String line; //the inputed line
collect = line.split(" "); //the conversion
System.out.println(stackem(collect)); // calling the stack method for an output method
The problem is that the output is always the operator ate the end of the line, so when I put in the code that checks for malformed expressions it always turns into the error. Basically my input would be like this:
input: 8 6 + 2 /
output: Error: "Expression is malformed"
output (without the error code): /
output (what's supposed to be the output): 7
This is the code for the stack method:
public String stackem(String[] input)
{
Stack<String> stack = new Stack<String>();
int x, y;
String result = "";
int get = 0;
String choice;
int value = 0;
String p = "";
int output;
try
{
for (int i = 0; i < input.length; i++)
{
if (input[i] == "+" || input[i] == "-" || input[i] == "*" || input[i] == "/" || input[i] == "^")
{
choice = input[i];
}
else
{
stack.push(input[i]);
continue;
}
switch (choice)
{
case "+":
x = Integer.parseInt(stack.pop());
y = Integer.parseInt(stack.pop());
value = x + y;
result = p + value;
stack.push(result);
break;
case "-":
x = Integer.parseInt(stack.pop());
y = Integer.parseInt(stack.pop());
value = y - x;
result = p + value;
stack.push(result);
break;
case "*":
x = Integer.parseInt(stack.pop());
y = Integer.parseInt(stack.pop());
value = x * y;
result = p + value;
stack.push(result);
break;
case "/":
x = Integer.parseInt(stack.pop());
y = Integer.parseInt(stack.pop());
value = y / x;
result = p + value;
stack.push(result);
break;
case "^":
x = Integer.parseInt(stack.pop());
y = Integer.parseInt(stack.pop());
value = (int)Math.pow(y,x);
result = p + value;
stack.push(result);
break;
default:
continue;
}
}
output = Integer.parseInt(stack.pop());
}
catch (Exception ex)
{
return "Error: Expression is malformed";
}
return "Result: " + output;
}
Is there any way to fix this issue?

Related

Java infix calculator logic

I am having trouble figuring out the logic for an infix calculator that is dynamic. I am able to accommodate string values with 5 elements, such as "1 + 1", but I cannot compute strings with more than 5 elements (ie: "1 + 2 + 3 + 4").
This is my process
import java.util.StringTokenizer;
public static int calculate(String input)
{
int lhs = 0;
int rhs = 0;
int total = 0;
char operation = ' ';
int intOne, intTwo;
StringTokenizer st = new StringTokenizer(input);
/*
* this block is chosen if there are no operations
*/
// block of if statement code for inputs less than or equal to
// 5 characters.
/*
* this block generates the correct number if there is more than
* one operator in the equation.
*/
}else if(input.length() > 5){
int firstValue = 0;
int latterValue = 0;
while(st.hasMoreTokens()){
/*
* method that assigns the left and right sides
*/
//assigns values to the first equation
int firstToken = Integer.parseInt(st.nextToken());
String opToken = st.nextToken();
int latterToken = Integer.parseInt(st.nextToken());
//returns a value for the first equation
firstValue = assignSides(firstToken, opToken, latterToken);
// takes in the next operator
if(st.nextToken().equals("+")){
operation = '+';
}else if(st.nextToken().equals("-")){
operation = '-';
}else if(st.nextToken().equals("*")){
operation = '*';
}else if(st.nextToken().equals("/")){
operation = '/';
}
// assigns values to the latter equation
firstToken = Integer.parseInt(st.nextToken());
opToken = st.nextToken();
latterToken = Integer.parseInt(st.nextToken());
//returns a value for the latter equation
latterValue = assignSides(firstToken, opToken, latterToken);
/*
* decides how to add the two equations
*/
switch(operation){
case '+': total = firstValue + latterValue;
break;
case '-': total = firstValue - latterValue;
break;
case '*': total = firstValue * latterValue;
break;
case '/': total = firstValue / latterValue;
break;
default: System.out.println("cannot compute");
break;
}
if(st.hasMoreTokens()){
//makes the total the first value
total = firstValue;
if(st.nextToken().equals("+")){
operation = '+';
}else if(st.nextToken().equals("-")){
operation = '-';
}else if(st.nextToken().equals("*")){
operation = '*';
}else if(st.nextToken().equals("/")){
operation = '/';
}
}
}
}
return total;
}
public static int assignSides(int firstToken, String opToken, int latterToken)
{
int lhs=0;
int rhs = 0;
int sum = 0;
char operation = ' ';
/*
* converts the string into a character
*/
if(opToken.equals("+")){
operation = '+';
}else if(opToken.equals("-")){
operation = '-';
}else if(opToken.equals("*")){
operation = '*';
}else if(opToken.equals("/")){
operation = '/';
}
rhs = latterToken;
/*
* interprates the character as a function
*/
switch(operation){
case '+': sum = lhs + rhs;
break;
case '-': sum = lhs - rhs;
break;
case '*': sum = lhs * rhs;
break;
case '/': sum = lhs / rhs;
break;
default: System.out.println("cannot compute");
break;
}
return sum;
}
Can I get help me with the error in my logic?
When calculating for more than 3 symbols (not counting spaces), as in "1 + 2 + 3",
you have to calculate in this order: 1 + (2 + 3).
You have to split up the first 1 and the remainig part "2 + 3", and pass the remaining part to the calculate method again. Something like:
int firstPart = ...; // evaluation of "1"
int secondPart = calculate("2 + 3");
int total = firstPart + secondPart;

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.

Postfix Evaluation using Stacks

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

Categories

Resources