I'm new to Java programming. I am trying to make a Fraction Calculator but when I try to run the program it gives me an error. The error is with the Switch statements but I don't know what happened.
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
System.out.println("Welcome to My FracCalc");
boolean continueProcessing = true;
while (continueProcessing) {
System.out.println("Type an expression and press <enter>");
String Operand1 = console.next();
if (Operand1.equals("quit")) {
continueProcessing = false;
System.out.println("Good bye!");
break;
} else {
Operand1 = parseFullNumber(Operand1);
}
String Operator = console.next();
if (Operator.equals("quit")) {
continueProcessing = false;
System.out.println("Good bye!");
break;
} else if (Operator.equals("+") || Operator.equals("-") || Operator.equals("/") || Operator.equals("*")) {
} else {
throw new ArithmeticException();
}
String Operand2 = console.next();
if (Operand2.equals("quit")) {
continueProcessing = false;
System.out.println("Good bye!");
break;
} else {
Operand2 = parseFullNumber(Operand2);
}
System.out.println( Operand1 + " " + Operator + " " + Operand2);
//System.out.println("First Fraction is: " + Operand1);
//System.out.println("Operator is: " + Operator);
//System.out.println("Second Fraction is: " + Operand2);
float answer;
System.out.println(Operator);
switch (Operator) {
case "+":
answer = Operand1 + Operand2;
break;
case "-":
answer = Operand1 - Operand2;
break;
case "*":
answer = Operand1 * Operand2;
break;
case "/":
answer = Operand1 / Operand2;
break;
}
}
}
public static String parseFullNumber(String input) {
int wholeNumber = 0;
int numerator = 0;
int denominator = 0;
;
int underscoreId = input.indexOf('_');
int slashId = input.indexOf('/');
// Check for underscore "_" //
if (underscoreId > -1) {
wholeNumber = Integer.parseInt(input.substring(0, underscoreId));
numerator = Integer.parseInt(input.substring(underscoreId + 1, slashId));
denominator = Integer.parseInt(input.substring(slashId + 1, input.length()));
} else {
if (slashId > -1) {
// no underscore but there is a slash //
numerator = Integer.parseInt(input.substring(0, slashId));
denominator = Integer.parseInt(input.substring(slashId + 1, input.length()));
} else {
// there is no underscore or slash //
wholeNumber = Integer.parseInt(input);
}
}
return simplify(wholeNumber, numerator, denominator);
}
//simplifying fractions //
public static String simplify(int wholeNumber, int numerator, int denominator) {
// absolute values //
int absNumerator = Math.abs(numerator);
// factor if applicable //
if (absNumerator > 1) {
int commonFactor = 1;
for (int i = 2; i < Math.min(absNumerator, denominator); i++) {
if (numerator % i == 0 && denominator % i == 0) {
commonFactor = i;
}
}
numerator /= commonFactor;
denominator /= commonFactor;
}
// reduce if applicable //
if (absNumerator > denominator) {
int reduction = numerator / denominator;
if (wholeNumber >= 0) {
wholeNumber += reduction;
} else {
wholeNumber -= reduction;
}
numerator %= denominator;
}
// prints //
if (wholeNumber != 0) {
if (numerator != 0) {
return wholeNumber + "_" + numerator + "/" + denominator;
} else {
return String.valueOf(wholeNumber);
}
} else {
if (numerator != 0) {
return numerator + "/" + denominator;
} else {
return String.valueOf(0);
}
}
}
}
Here is the error i got:
Exception in thread "main" java.lang.Error:
Unresolved compilation problems:
Type mismatch:
cannot convert from String to float The operator - is undefined for the argument type(s) java.lang.String, java.lang.String
The operator * is undefined for the argument type(s) java.lang.String, java.lang.String
The operator / is undefined for the argument type(s) java.lang.String, java.lang.String
at FracCalcApp.main(FracCalcApp.java:53)
Operand1 and Operand2 are String(s). You need to parse them before you can perform arithmetic. Something like,
double answer;
System.out.println(Operator);
switch (Operator) {
case "+":
answer = Double.valueOf(Operand1) + Double.valueOf(Operand2);
break;
case "-":
answer = Double.valueOf(Operand1) - Double.valueOf(Operand2);
break;
case "*":
answer = Double.valueOf(Operand1) * Double.valueOf(Operand2);
break;
case "/":
answer = Double.valueOf(Operand1) / Double.valueOf(Operand2);
break;
}
Finally, by convention, Java variables should start with a lower case letter; operand1, operand2 and operator.
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("Enter first number");
float a = sc.nextFloat();
System.out.println("Enter second number");
float b = sc.nextFloat();
System.out.println("choose your operation");
char operator = sc.next().charAt(0);
float answer;
switch (operator){
case '+' :
answer = a +b;
System.out.println("Answer:"+answer);
break;
case '-' :
answer = a-b;
System.out.println("Answer:"+answer);
break;
case '*' :
answer = a*b;
System.out.println("Answer:"+answer);
break;
default:
answer = a/b;
System.out.println("Answer:"+answer);
}
}
Related
I wanna write a program that that take a infix string and change it to postfix then evaluate postfix and print the answer ; for +-*/^ it's easy just need precedence of operators but I don't know what should I do for sin cos log and other math function.
private static String infixToPostfix(String infix) {
String[] exp = infix.split("");
Stack<String> stack = new Stack<>();
String result = "";
for (int i = 0; i < exp.length; i++){
if (exp[i].equals("(")) {
stack.push(exp[i]);
}
else if (isOperator(exp[i]))
{
while (!stack.isEmpty() && precedence(exp[i]) <= precedence(stack.getTop())){
result += stack.pop() + " ";
}
stack.push(exp[i]);
}
else if (exp[i].equals(")"))
{
while (!stack.isEmpty() && !stack.getTop().equals("(")){
result += stack.pop() + " ";
}
stack.pop();
}
else if (Character.isLetterOrDigit(infix.charAt(i)) || exp[i].equals(".")){
boolean haveDot = exp[i].equals(".");
String temp = haveDot ? "0." : exp[i];
while ((i + 1) < exp.length && (Character.isLetterOrDigit(infix.charAt(i + 1)) || exp[i + 1].equals("."))){
temp += exp[i + 1];
i++;
}
result += temp + " ";
}
}
while (!stack.isEmpty()){
result += stack.pop() + " ";
}
return result;
}
it is working correctley !
but this
private static Double postFixEvaluator(String[] postFix) {
Stack<Double> operands = new Stack<>();
double value = 0.0;
for (int str = 0; str < postFix.length; str++) {
if (postFix[str].trim().equals("")) {
continue;
}
switch (postFix[str]) {
case "+":
case "-":
case "*":
case "/":
case "^":
Double right = operands.pop();
Double left = operands.pop();
long intValue = 0;
switch (postFix[str]) {
case "+":
value = left + right;
break;
case "-":
value = left - right;
break;
case "*":
value = left * right;
break;
case "/":
value = left / right;
break;
case "^":
value = Math.pow(left, right);
break;
default:
break;
}
case "sin":
case "cos":
case "tan":
case "cot":
if (Character.isLetterOrDigit(Arrays.toString(postFix).charAt(str + 2))) {
str++;
break;
}
else{
Double oper = operands.pop();
switch (postFix[str]) {
case "sin":
value = Math.sin(oper);
break;
case "cos":
value = Math.cos(oper);
break;
case "tan":
value = Math.tan(oper);
break;
case "cot":
value = 1 / Math.tan(oper);
break;
}
}
operands.push(value);
break;
default:
operands.push(Double.parseDouble(postFix[str]));
break;
}
}
return operands.pop();
}
it's not working correctly .
One of the problems that I'm having is that I can't use Camel case. I have to use Pascal. I found out while correcting the below code that when I change the int to a double like our instructor wants, I get a cannot switch on a value of type double.
I am trying to look for something else to use instead of a switch that can get me the same functionality. Any help is appreciated. Thanks!
import java.util.Random;
import java.util.Scanner;
public class CalculatorWithMethods {
// scanner object creation
static Scanner input = new Scanner(System.in);
boolean mainloop = true;
public static void main(String[] args) {
//Declaring variables
double res;
//calling the method
double choice = getMenuOption();
switch (choice) {
case 1:
{
//calling the method to get the operands
double operand1 = getOperand("What is the first number?");
double operand2 = getOperand("What is the second number?");
res = add(operand1, operand2);
System.out.println(operand1 + " + " + operand2 + " = " + res);
break;
}
case 2:
{
//calling the method to get the operands
double operand1 = getOperand("What is the first number?");
double operand2 = getOperand("What is the second number?");
res = subtract(operand1, operand2);
System.out.println(operand1 + " - " + operand2 + " = " + res);
break;
}
case 3:
{
//calling the method to get the operands
double operand1 = getOperand("What is the first number?");
double operand2 = getOperand("What is the second number?");
res = multiply(operand1, operand2);
System.out.println(operand1 + " * " + operand2 + " = " + res);
break;
}
case 4:
{
//calling the method to get the operands
double operand1 = getOperand("What is the first number?");
double operand2 = getOperand("What is the second number?");
if (operand2 == 0) {
System.out.println("The Second Number is Double.NAN.");
} else {
//calling the method to get the operands
operand1 = getOperand("What is the first number?");
operand2 = getOperand("What is the second number?");
res = divide(operand1, operand2);
System.out.println(operand1 + " / " + operand2 + " = " + res);
}
break;
}
case 5:
{
double operand1 = getOperand("What is the lower limit ?");
double operand2 = getOperand("What is the upper limit ?");
res = random(operand1, operand2);
System.out.println("The Random Number is :" + res);
break;
}
}
}
//This method will perform the add operation
public static double add(double operand1, double operand2) {
return operand1 + operand2;
}
//This method will perform the subtract operation
public static double subtract(double operand1, double operand2) {
return operand1 - operand2;
}
//This method will perform the multiply operation
public static double multiply(double operand1, double operand2) {
return operand1 * operand2;
}
//This method will perform the division operation
public static double divide(double operand1, double operand2) {
return operand1 / operand2;
}
//This method returns the random number
public static double random(double x, double y) {
Random generator = new Random();
return generator.nextInt((int)(y - x) + 1) + x;
}
//This method will get the operands entered by the user
public static double getOperand(String str) {
System.out.print(str);
double num = input.nextDouble();
return num;
}
//This method will display the menu
public static int getMenuOption() {
int choice;
// user interaction until quit performed.
while (true) {
// displaying menu
System.out.println("\nMenu\n1. Add\n2. Subtract\n3. Multiply\n4. Divide\n5. Generate Random Number\n6. Quit");
// ask user choice
System.out.println("What would you like to do?");
choice = input.nextInt();
if (choice < 1 || choice > 5) {
System.out.println("** Invalid Choice **");
continue;
} else {
return choice;
}
}
}
}
After this:
//calling the method
double choice = getMenuOption();
do this:
long intCastedChoice = (long)choice;
Then switch the intCastedChoice instead.
public static int evaluate(Scanner input)
{
if (input.hasNextInt())
{
return input.nextInt();
}
else
{
String operator = input.next();
int operand1 = evaluate(input);
int operand2 = evaluate(input);
return evaluate(operator, operand1, operand2);
}
}
// pre : operator is one of *, /, %, + or -
// post: returns the result of applying the given operator to
// the given operands
public static int evaluate(String operator, int operand1, int operand2)
{
if (operator.equals("*"))
{
return operand1 * operand2;
}
else if (operator.equals("/"))
{
return operand1 / operand2;
}
else if (operator.equals("%"))
{
return operand1 % operand2;
}
else if (operator.equals("+"))
{
return operand1 + operand2;
}
else if (operator.equals("-"))
{
return operand1 - operand2;
}
else
{
throw new RuntimeException("illegal operator " + operator);
}
}
I want to take this code and convert it to 2 stacks (one stack for the operators and the other stack for the operands) for using prefix expressions in a user-input GUI with an actionlistener. How can I write the code to convert this code to 2 stacks? By the way, this is homework and I understand that you're not allowed to give me the answers outright, so if you can provide me easy-to-understand pseudo code, that will be much appreciated. Thank you for your help.
Your pseudo is here:
public static int evaluate(Scanner input)
{
if (input.hasNextInt())
{
int stack_top_value=input.nextInt();
stack_for_operand.push(stack_top_value);
return stack_top_value;
}
else
{
String operator = input.next();
stack_for_operator.push(operator);
int operand1 = evaluate(input);
int operand2 = evaluate(input);
return evaluate(operator, operand1, operand2);
}
}
I'm a java beginner trying to make a calculator that can accept mixed numbers and fractions, but rather than calculating the values it's just combining the two. (ex.1 + 1/2
The answer is 11/2
)` import java.util.Scanner;
public class Calculator {
public static void main(String[] args) {
Scanner Woith = new Scanner(System.in);
System.out.println("Welcome to the Calc-O-Lator 9000\nthis calculator is able to\nadd, subtract, mulitiple, divide, and handle exponents of\nFRACTIONS\n\nenter 'quit' when done");
System.out.println("To input a mixed number use an underscore in addition with a slash(ex. 2_1/2), also provide a space between the first number and operator\n and the operator and the second number.");
Boolean on=true;
Scanner console=new Scanner(System.in);String firstNumber = Woith.next();
if (firstNumber.equals("quit")) {
on = false;
System.out.println("goodbye");
} else {
firstNumber = parseFullNumber(firstNumber);
}
String operator = Woith.next();
if (operator.equals("quit")) {
on = false;
System.out.println("goodbye");
} else if (operator.equals("+") || operator.equals("-") || operator.equals("/") || operator.equals("*")) {
} else {
throw new ArithmeticException();
}
String secondNumber = Woith.next();
if (secondNumber.equals("quit")) {
on = false;
System.out.println("goodbye");
} else {
secondNumber = parseFullNumber(secondNumber);
}
int wholeNumber = 0;
int numerator = 0;
int denominator = 0;
System.out.println(calculate(operator , firstNumber, secondNumber, wholeNumber, numerator, denominator));
}
public static String parseFullNumber(String input) {
int wholeNumber = 0;
int numerator = 0;
int denominator = 0;
int underscoreIdx = input.indexOf('_');
int slashIdx = input.indexOf('/');
if (underscoreIdx > -1) {
wholeNumber = Integer.parseInt(input.substring(0, underscoreIdx));
numerator = Integer.parseInt(input.substring(underscoreIdx + 1, slashIdx));
denominator = Integer.parseInt(input.substring(slashIdx + 1, input.length()));
} else {
if (slashIdx > -1) {
numerator = Integer.parseInt(input.substring(0, slashIdx));
denominator = Integer.parseInt(input.substring(slashIdx + 1, input.length()));
} else {
wholeNumber = Integer.parseInt(input);
}
}
return reduce(wholeNumber, numerator, denominator);
}
public static String reduce(int wholeNumber, int numerator, int denominator) {
int absNumerator = Math.abs(numerator);
if (absNumerator > 1) {
int commonFactor = 1;
for (int i = 2; i < Math.min(absNumerator, denominator); i++) {
if (numerator % i == 0 && denominator % i == 0) {
commonFactor = i;
}
}
numerator /= commonFactor;
denominator /= commonFactor;
}
if (absNumerator > denominator) {
int reduction = numerator / denominator;
if (wholeNumber >= 0) {
wholeNumber += reduction;
} else {
wholeNumber -= reduction;
}
numerator %= denominator;
}
if (wholeNumber != 0) {
if (numerator != 0) {
return wholeNumber + "_" + numerator + "/" + denominator;
} else {
return String.valueOf(wholeNumber);
}
} else {
if (numerator != 0) {
return numerator + "/" + denominator;
} else {
return String.valueOf(0);
}
}
}
public static String calculate(String input, String firstNumber,String secondNumber,int wholeNumber,int numerator,int denominator){
if (input.contains ("+"))
{
if(!input.contains("/")){
return ("The answer is "+firstNumber + secondNumber);
}
if (input.contains("/")){
return ("The answer is "+(numerator*denominator)+(numerator*denominator)+"/"+(numerator*denominator));
}
if(input.contains("_")){
return ("The answer is "+wholeNumber+numerator+"/"+denominator);
}
if(input.contains("-")){
if(!input.contains("/")){
return ("The answer is "+firstNumber + secondNumber);
}
if (input.contains("/")){
return ("The answer is "+(numerator*denominator)+"/"+(numerator*denominator));
}
if(input.contains("_")){
return ("The answer is "+wholeNumber+numerator+"/"+denominator);
}
if(input.contains("*")){
if(!input.contains("/")){
return ("The answer is "+firstNumber + secondNumber);
}
if (input.contains("/")){
return ("The answer is "+(numerator*numerator)+"/"+(denominator*denominator));
}
if(input.contains("_")){
return ("The answer is "+wholeNumber+numerator+"/"+denominator);
}
}
}
}
return input;
}
}
Well, other problems from your code aside, your problem "1 + 1/2 The answer is 11/2" originates from here:
if (input.contains("/")){
return ("The answer is "+(numerator*denominator)+(numerator*denominator)+"/"+(numerator*denominator));
}
The output you stated is correct as that is string concatenation. You really want float conversion, so try this instead:
if (input.contains("/")) {
return ("The answer is "+(numerator*denominator)+((float)(numerator*denominator)/(numerator*denominator)));
}
This is because you used "+" opeartion for the String values.
e.g.
The firstNumber is a type of String, like "1"
The secondNumber is a type of String, like "1/2"
In calculate method, You print answer using the following way
if(!input.contains("/")){
return ("The answer is "+firstNumber + secondNumber);
}
Here will return a string value of "
The answer is 11/2"
That's what you are encountering (ex.1 + 1/2 The answer is 11/2)
I have this method which will generate a random maths expression solve it and output the answer to a variable:
public int Nov2()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
int novnum1 = rand.nextInt(101-1) + 1;
int novnum2 = rand.nextInt(101-1) + 1;
int nov2result = 0;
switch(op1) {
case '+': nov2result = novnum1 + novnum2; break;
case '-': nov2result = novnum1 - novnum2; break;
case '*': nov2result = novnum1 * novnum2; break;
case '/': nov2result = novnum1 / novnum2; break;
}
String nov2Exp = novnum1 + " " + op1 + " " + novnum2 + " = ";
Nov2resstor = nov2result;
setContentView(R.layout.gameview);
TextView display = (TextView) findViewById(R.id.exp);
display.setText(nov2Exp);
return nov2result;
}
How would i use the same sort of thing for expressions with more than two terms without having to write really complex if statements like this in my next method:
public int Eas3()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
i = rand.nextInt(4-0) + 0;
char op2 = ops[i];
int easnum1 = rand.nextInt(101-1) + 1;
int easnum2 = rand.nextInt(101-1) + 1;
int easnum3 = rand.nextInt(101-1) + 1;
int eas3result = 0;
if (op1 == '+' && op2 == '+')
{
eas3result = ((easnum1 + easnum2) + easnum3);
}
else if (op1 == '+' && op2 == '-')
{
eas3result = ((easnum1 + easnum2) - easnum3);
}
else if (op1 == '+' && op2 == '*')
{
eas3result = ((easnum1 + easnum2) * easnum3);
}
else if (op1 == '+' && op2 == '-')
{
eas3result = ((easnum1 + easnum2) - easnum3);
}
.../
I have methods which do this for 2,3,4,5 and 6 so my if statements would become very large using this method.
Any ideas?
you can use the built-in Javascript engine.
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Test
{
public static void main(String[] args) throws Exception
{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}
Yes, another way to do it is to write Command objects:
public interface Command<V> {
V execute(Object ... args);
}
You'll write an object that implements this interface:
public class AdditionCommand implements Command<Double> {
public Double execute(Object ... args) {
Double x = (Double)args[0];
Double y = (Double)args[1];
return x+y;
}
}
Now you can look up in a Map using the operator:
Map<String, Command> opsLookup = new HashMap<String, Command>() {{
opsLookup.put("+", new AddCommand<Number>());
opsLookup.put("-", new SubtractCommand<Number>());
}};
No need for a switch.
Check out this MathEval class I found online It will evaluate a String that represents an equation for you.
mySolver = new MathEval();
double answer = mySolver.evaluate(equation);
What you're looking for is called the composite pattern. You define an abstract Expression base class and derive it.
The classes must implement an evaluate() method which returns the result.
One sub class will be the constant which return it's value, another one would be a binary expression like plus, minus, etc. The evaluate() method will add/subtract/etc the result of the evaluated sub-expressions.
You can then build arbitrary expressions out of other expressions and then evaluate it without using one if condition.
How about using recursion:
int num(int numberOfOperands, int current){
if(numberOfOperands<=0) return current;
switch(rand.nextInt(4)){
case 0: return num(numberOfOperands-1, current + (rand.nextInt(100)+1)); break;
case 1: return num(numberOfOperands-1, current - (rand.nextInt(100)+1)); break;
case 2: return num(numberOfOperands-1, current * (rand.nextInt(100)+1)); break;
case 3: return num(numberOfOperands-1, current / (rand.nextInt(100)+1)); break;
}
}
int num(int numberOfOperands) throws Exception{
if(numberOfOperands <=0)
throw new Exception("invalid number of operands: "+numberOfOperands);
return num(numberOfOperands, rand.nextInt(100)+1);
}
This would, of course, ignore precedence of operations.
You could make a string with the variables you are using like this:
String temp = "(" + easnum1 + op1 + easnum2 + ")" + op2 + easnum3;
after that you can use the ScriptEngineManager class to use javascript as the engine so you can use the eval method.
ScriptEngineManager manager = new ScriptEngineManager();
ScriptEngine engine = manager.getEngineByName("js");
Object result = engine.eval(temp);
this method does the calculations and returns the result.
Hope this helps.
I would use an array for the values easnum[], an array for the operands op[] and an array with intermediate values.
Something along the following lines
for(...)
{
if(op[i]=='+') easintermediat[i+1] = easintermediate[i] + easnum[i]
...
}
If you've got n operations on n+1 numbers, and you do the first one, then you're left with n-1 operations on n numbers. You can use this as the basis for a loop that will process any number of items easily.
int operate(int[] numbers, int[] operations) {
if (numbers.length < 1 || numbers.length != operations.length + 1) {
throw new IllegalArgumentException();
}
int result = numbers[0];
for (int i = 0; i < operations.length; ++i) {
result = operate(operations[i], result, numbers[i+1]);
// where operate() is your switch statement
}
return result;
}
Try this:
public int Eas3()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
i = rand.nextInt(4-0) + 0;
char op2 = ops[i];
int easnum1 = rand.nextInt(101-1) + 1;
int easnum2 = rand.nextInt(101-1) + 1;
int easnum3 = rand.nextInt(101-1) + 1;
int eas3result = 0;
if (op1 == '+')
{
switch(op2)
{
case '+': eas3result=((easnum1 + easnum2) + easnum3); break;
case '-': eas3result=((easnum1 - easnum2) - easnum3); break;
case '*': eas3result=((easnum1 * easnum2) * easnum3); break;
case '/': eas3result=((easnum1 / easnum2) / easnum3); break;
}
}
..../
}
or even you can put outer IF in SWITCH like the following
public int Eas3()
{
char[] ops = new char[] {'+', '-', '*', '/'};
int i = rand.nextInt(4-0) + 0;
char op1 = ops[i];
i = rand.nextInt(4-0) + 0;
char op2 = ops[i];
int easnum1 = rand.nextInt(101-1) + 1;
int easnum2 = rand.nextInt(101-1) + 1;
int easnum3 = rand.nextInt(101-1) + 1;
int eas3result = 0;
int tempResult=0;
switch(op1)
{
case '+': tempResult=(easnum1 + easnum2); break;
case '-': tempResult=(easnum1 + easnum2) ; break;
case '*': tempResult=(easnum1 + easnum2) ; break;
case '/': tempResult=(easnum1 + easnum2) ; break;
}
switch(op2)
{
case '+': eas3result=(tempResult + easnum3); break;
case '-': eas3result=(tempResult - easnum3); break;
case '*': eas3result=(tempResult * easnum3); break;
case '/': eas3result=(tempResult / easnum3); break;
}
}