Java infix calculator logic - java

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;

Related

RPN stacking method not working with converted string arrays

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?

How to add 14 based numbers in instance method?

So I'm having trouble with creating an instance method to add two 14-based number and I was wondering if anyone could help? I'm a bit new to java and still sort of confused on the whole thing. So far I have the code to convert the 14-based numbers to base 10 then I need to add them and convert them back to base-14. I want to put them all in once instance class, but I feel like it's too much to put into one instance class.
This is the kind of input I was for the client code to be like this:
PokerNum sum = num1.add(num2);
import java.util.Scanner;
public class PokerNum{
String alienNum;
int num1, num2;
public PokerNum(String alienNum) throws IllegalArgumentException{
this.alienNum = alienNum;
String toUpper = alienNum.toUpperCase();
for (int i = 0; i < toUpper.length(); i++){
char c = toUpper.charAt(i);
if (!(Character.isDigit(c) || c == 'A' || c == 'J' || c == 'Q' || c == 'K')){
throw new IllegalArgumentException("invalid input");
}
}
}
// initialized at zero
public PokerNum() {
this.num1=0;
this.num2=0;
}
#Override public String toString(){
return PokerNum()+ " ";
}
//add pokernums
public PokerNum add(PokerNum another){
PokerNum num = new PokerNum();
this.num1 = another.num1;
this.num2 = another.num2;
public PokerNum convert(PokerNum pn){
char[] firstNum = num1.toCharArray();
int amountValue = 0;
int length = characters.length;
for (int index = 0; index < length; index++){
int symbolValue;
switch (characters[index]) {
case 'A':
symbolValue = 10;
break;
case 'J':
symbolValue = 11;
break;
case 'Q':
symbolValue = 12;
break;
case 'K':
symbolValue= 13;
break;
default:
symbolValue = characters[index] - 48;
}
amountValue += symbolValue*Math.pow(14, length - index - 1);
}
StringBuilder result1 = new StringBuilder();
while(amountValue > 0){
int digit = amountValue%14;
switch (digit) {
case 10:
result.insert(0, 'A');
break;
case 11:
result.insert(0, 'J');
break;
case 12:
result.insert(0, 'Q');
break;
case 13:
result.insert(0, 'K');
break;
default:
result.insert(0, digit);
}
amountValue-=digit;
amountValue/=14;
String firstValue = result1.toString();
}
}
char[] secNum = num2.toCharArray();
int amountValue2= 0;
int length = secNum.length;
for (int index = 0; index < length; index++){
int symbolValue;
switch (characters[index]) {
case 'A':
symbolValue = 10;
break;
case 'J':
symbolValue = 11;
break;
case 'Q':
symbolValue = 12;
break;
case 'K':
symbolValue= 13;
break;
default:
symbolValue = characters[index] - 48;
}
amountValue2+= symbolValue*Math.pow(14, length - index - 1);
}
StringBuilder result = new StringBuilder();
while(amountValue2> 0){
int digit = amountValue%14;
switch (digit) {
case 10:
result.insert(0, 'A');
break;
case 11:
result.insert(0, 'J');
break;
case 12:
result.insert(0, 'Q');
break;
case 13:
result.insert(0, 'K');
break;
default:
result.insert(0, digit);
}
amountValue2-=digit;
amountValue2/=14;
PokerNum secondValue = result.toString();
}
return firstValue + secondValue;
/*PokerNum sum = num1 +
PokerNum another.num2 =
return sum;*/
}
Thanks to anyone who helps in advance :)
I believe you can keep it in one instance. One suggestion is to use the conversion using the following functions:
Integer.parseInt(String s, int radix)
Integer.toString(int i, int radix)
The javadoc says that the string produced will use:
0123456789abcdefghijklmnopqrstuvwxyz
So, if we choose radix = 14, it will have 0123456789abcd.
The logic idea is to keep the actual number as int, and to convert at creation and at printout from and to String. We can just keep member variable num1 and remove the member variable alienNum and num2.
Constructor
Your constructor with String argument seems to do a good error checking. What we need here is just to convert from string to integer and store it in the member variable. First we need to convert all valid string from AJQK to ABCD. The example here is inefficient, but gets the idea across:
//alienNum = alienNum.replace('A', 'A'); // no need
alienNum = alienNum.replace('J', 'B');
alienNum = alienNum.replace('Q', 'C');
alienNum = alienNum.replace('K', 'D');
Then we can call the parsing method:
num1 = Integer.parseInt(alienNum , 14);
Your empty arg constructor is already fine by initializing the value of num1 to 0.
Adding
The method inside addition is not right because it is setting the current value to the addition. There are three objects working here: num, this, and another. You want to add this to another into num and return num.
num.num1 = this.num1 + another.num1;
Output
I'm assuming the output is going to be from toString(). In this case, you want to convert from integer to string, then convert it to the right character
String out = Integer.toString(num1, 14).toUpper();
//alienNum = alienNum.replace('A', 'A'); // no need
alienNum = alienNum.replace('B', 'J');
alienNum = alienNum.replace('C', 'Q');
alienNum = alienNum.replace('D', 'k');
You probably won't need a convert method now.

Menu Driven Program 1

I Need to write a menu driven program to allow the user to input two polynomials and then provide the user with a menu of options, I have already written the part of the code to input two polynomials... But i am struggling with the menu of options... the first option on the menu is to "evaluate the first polynimal at a value of x specified by the user". Here is my code so far :`
import java.util.Scanner;
public class Polynomial2 {
public static void main(String[] args) {
int i, coef, x, deg, count = 2;
double total = 0.0, result;
char opt;
Scanner sc = new Scanner(System.in);
do {
System.out.println("Enter Degree");
deg = sc.nextInt();
System.out.println("Enter x");
x = sc.nextInt();
for (i = 0; i <= deg; i++) {
System.out.println("Enter Coefficent for " + i);
coef = sc.nextInt();
total = total + coef * Math.pow(x, i);
}
count--;
} while (count > 0);
System.out.println("Total=" + total);
{
coef = sc.nextInt();
result = sc.nextDouble();
opt = sc.next().charAt(0);
switch (opt) {
case 'a':
result = total + coef * Math.pow(x, i);
System.out.println("Evalute Polynomial 1 at x");
break;
case 'b':
result = total + coef * Math.pow(x, i);
System.out.println("Evaluate Polynomial 2 at x");
break;
case 'c':
result = total + total;
System.out.println("Add Polynomial 1 and 2");
break;
case 'd':
result = total - total;
System.out.println("Subtract Polynomial 1 from Polynomial 2");
break;
case 'e':
result = total - total;
System.out.println("Subtract Polynomial 2 from Polynomial 1");
break;
case 'f':
result = total * x;
System.out.println("Multiply Polynomial 1 by a constant");
break;
case 'g':
result = total * x;
System.out.println("Multiple Polynomial 2 by a constant");
break;
}
}
}
}
This is incoherent as a menu. To set up a basic menu program you need to give the user a print out of the Menu options and then use your scanner to receive their menu selection, then do an action based on that. Trying to guess what you need your menu to do from your code, I would do something like the following:
String menuPrompt = "Please select from the following options:\n\n" +
"a - Evaluate Polynomial 1 at x\n" +
"b - Evaluate Polynomial 2 at x\n" +
"c - Add Polynomial 1 and 2\n" +
"d - Subtract Polynomial 1 from Polynomial 2\n" +
"e - Subtract Polynomial 2 from Polynomial 1\n" +
"f - Multiply Polynomial 1 by a constant\n" +
"g - Multiple Polynomial 2 by a constant\n\n" +
"Enter selection: ";
System.out.print(menuPrompt);
char opt = sc.nextChar();
switch(opt) {
case 'a':
result = total + coef * Math.pow(x, i);
break;
case 'b':
//...etc...
}

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.

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