Making a simple calculator: cannot exit loop or give answer - java

I need to make a simple calculator. I am having trouble with entering any amount of operators and operands, then outputting the answer when the equals button has been entered.
So far, if I just press one number and a digit it exits but does not give me an answer. If I do more than one operator and operand then = it does not exit the loop.
For example it should be like:
5
+
5
+
5
=
15
Here is my code, Calculator:
public interface Calculator {
public void setOperator(char operator); // eg +-*/=
public void setOperand (double operand); // eg 123.456
public double getResult();
}
SimpleCalculator:
import java.io.*;
public class SimpleCalculator implements Calculator {
char operator;
double operand;
double result;
double answer;
public void setOperator(char operator){
this.operator = operator;
}
public char getOperator(){
return operator;
}
public void setOperand(double operand){
this.operand = operand;
}
public double getOperand(){
return operand;
}
public double getResult(){
if (getOperator() == '+'){
result = (getOperand() + getOperand());
}
if (getOperator() == '-'){
result = (getOperand() - getOperand());
}
if (getOperator() == '*'){
result = (getOperand() * getOperand());
}
if (getOperator() == '/')
{
result = (getOperand() / getOperand());
}
if (getOperator() == '=')
result = answer;
}
return result;
}
public boolean getanswer(String value)
{
boolean isnum = false;
try {
setOperand(Double.parseDouble(value));
operand = (Double.parseDouble(value));
getResult();
isnum = true;
}
catch(Exception e)
{
try {
setOperator(value.charAt(0));
operator = (value.charAt(0));
isnum = false;
}
catch(Exception e2)
{
{
System.out.println("Enter a number");
}
}
return isnum;
}
}
SimpleTest:
import java.io.*;
public class SimpleTest{
static String value;
static double operand;
static char operator;
static boolean isnum;
public static void main(String[] argv){
SimpleCalculator calculator = new SimpleCalculator();
value = UserInput.readString();
while (!(value.equals("=")))
{
isnum = calculator.getanswer(value);
if (!(isnum == true))
{
break;
}
}
System.out.println(calculator.getResult());
}
}

Based on the title of your question I found that you might see an issue with your main-loop:
value = UserInput.readString();
while (!(value.equals("="))) {
isnum = calculator.getanswer(value);
if (!(isnum == true)) {
break;
}
}
Since you read the user input outside the loop it will never change and this will either run only once (if isnum is false) or infinitely (if isnum is true) -- getanswer does not has a memory with respect to its result. Thus if you input a number it will loop forever but not doing anything useful.
Please note: this is just a first guess. I didn't check the rest of your program.

You didn't really say what your problem is, but I found one for you:
You are using
result = (getOperand() + getOperand();
(and similar) to calculate your results. But getOperand() always returns the same result (since you can't execute setOperand() between these calls), so you are always adding, subtracting, multiplying and dividing the same number.

Related

My program keeps returning a StringIndexOutOfBounds Exception regardess of what I do

import java.io.*;
public class runner{
//Translates from infix to postfix
//Evaluates the postfix expression
public static tokenlist xform(String input){
//operand get pushed automatically onto linked list
//operator we will see;
tokenlist postfix=new tokenlist();
stack stack=new stack();
int c=0;
while(input.substring(c,c) != null){
if(prec.isoper(input.substring(c,c))==false){
postfix.push(input.substring(c,c),false);
}else{
if(stack.inspect()==null){
stack.push(input.substring(c,c));
}else{
if(prec.inprec(input.substring(c,c))>prec.stackprec(stack.inspect())){
while(prec.inprec(input.substring(c,c))>prec.stackprec(stack.inspect())){
String s=stack.pop();
postfix.push(s,true);
}
}else{
stack.push(input.substring(c,c));
}
}
}
c++;
}
return postfix;
}
public static double eval(tokenlist postfix){
astack numbers=new astack();
Double ans=0.0;
numbers.push(Double.parseDouble(postfix.getTing()));
while(numbers.isEmpty() != true){
if(postfix.getFunc()== false){
numbers.push(Double.parseDouble(postfix.getTing()));
}else{
double c=0.0;
double a=numbers.pop();
double b=numbers.pop();
if(postfix.getTing()=="+"){
c=a+b;
numbers.push(c);
}
if(postfix.getTing()=="-"){
c=b-a;
numbers.push(c);
}
if(postfix.getTing()=="*"){
c=a*b;
numbers.push(c);
}
if(postfix.getTing()=="/"){
c=b/a;
numbers.push(c);
}
if(postfix.getTing()=="^"){
double store;
double rep=0.0;
while(rep<=a){
c=b*b;
store=c;
rep=rep+1.0;
}
numbers.push(c);
}
if(postfix.getTing()=="\\"){
c=Math.abs(b-a);
numbers.push(c);
}
}
ans=numbers.pop();
}
return ans;
}
public static void main(String[] args){
try{
tokenlist postfix=xform(args[0]);
postfix.printlist();
double d=eval(postfix);
System.out.println(d);
}catch(Exception e){System.out.print(e);}
}
}
Regardless of what number is within args[#] in the main, I keep geting the above exception and String index out of range: Whatever number is in args[#] in the main. I already checked in the xform and it takes in the input as a string and the substring starts at 0. Still it doesn't work. I f anyone could have an explanation or tips they would be greatly appreciated.
You're code contains the line while(input.substring(c,c) != null)
This is basically an endless loop until c is higher that the length of your string which causes the exception.
Try to change it to while(c < input.length()) and you should be good to go.
Furthermore I hope you are aware of the fact that substring(c,c) will always return an empty string.
If you want a single character either use .charAt(c) or .substring(c, c+1)

Java contains a string or not?

http://codingbat.com/prob/p126880
Given two strings, return true if either of the strings appears at the very end of the other string, ignoring upper/lower case differences (in other words, the computation should not be "case sensitive"). Note: str.toLowerCase() returns the lowercase version of a string.
I cannot get when it is true, it always gives false.
public boolean endOther(String a, String b)
{
//variables
a.toLowerCase();
b.toLowerCase();
String f1="";
String f2="";
int d=0;
int sum=0;
//Program code;
if(a.length()-b.length()>0)
{
(f1).equals(a);
(f2).equals(b);
d=a.length();
}
else if(a.length()-b.length()<0)
{
(f1).equals(b);
(f2).equals(a); //gett**ing bigger and lower String**
d=b.length();
}
else if((a).equals(b))
sum++;
// I think problem is because it is not enter the for.
for(int i=0; i>d; i++)
{
if((f1.substring(i,i+f2.length())).equals(f2))
sum++;
}
if(sum>0)
return true;
else
return false;
}
This is a working example of what you are trying to achieve to test in your Java IDE like Netbeans or Eclipse whatever. This is really simple, the String object has an endsWith method so why try to invent something yourself.
If you have any troubles reading this code hit me up, should be quite straight forward. You will just have to convert your string to lowercase, that's for you to add.
public class StringEnds {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.printf("String a: ");
String a = scanner.next();
System.out.printf("String b: ");
String b = scanner.next();
// Compare a and b
if (endsWith(a, b)) {
System.out.printf("Succes\n");
} else {
System.out.printf("Fail\n");
}
}
public static boolean endsWith(String firstString, String secondString) {
return firstString.endsWith(secondString) || secondString.endsWith(firstString);
}
}
Here's your codebat solution (it is quite short):
public boolean endOther(String a, String b) {
return a.toLowerCase().endsWith(b.toLowerCase()) || b.toLowerCase().endsWith(a.toLowerCase());
}
This is my answer. I tried both ways, hope it helps.
public boolean endOther(String a, String b) {
int small = Math.min(a.length(), b.length());
if (a.length()==b.length() && a.equalsIgnoreCase(b)) {
return true;
}
if (small==a.length()) {
if (b.substring(b.length()-small).equalsIgnoreCase(a)) {
return true;
}
// from here is the toLowerCase() method.
a = a.toLowerCase();
b = b.toLowerCase();
} else if (small==b.length()) {
if (a.endsWith(b)) {
return true;
}
}
return false;
}

infix arithmetic expression definition

How is the grammar for infix arithmetic expressions, defined? I have code of a infix 'calculator', but I need to know, in words or some type of examples how to define the grammar.
the code:
import java.util.Stack;
import java.util.StringTokenizer;
public class Infix
{
public double infix(String expression)
{
expression=expression.replaceAll("[\t\n ]", "")+"=";
String operator="*/+-=";
StringTokenizer tokenizer=new StringTokenizer(expression, operator, true);
Stack operatorStack=new Stack();
Stack valueStack=new Stack();
while(tokenizer.hasMoreTokens())
{
String token=tokenizer.nextToken();
if(operator.indexOf(token)<0)
valueStack.push(token);
else
operatorStack.push(token);
resolve(valueStack, operatorStack);
}
String lastOne=(String)valueStack.pop();
return Double.parseDouble(lastOne);
}
public int getPriority(String op)
{
if(op.equals("*") || op.equals("/"))
return 1;
else if(op.equals("+") || op.equals("-"))
return 2;
else if(op.equals("="))
return 3;
else
return Integer.MIN_VALUE;
}
public void resolve(Stack values, Stack operators)
{
while(operators.size()>=2)
{
String first=(String)operators.pop();
String second=(String)operators.pop();
if(getPriority(first)<getPriority(second))
{
operators.push(second);
operators.push(first);
return;
}
else
{
String firstValue=(String)values.pop();
String secondValue=(String)values.pop();
values.push(getResults(secondValue, second, firstValue));
operators.push(first);
}
}
}
public String getResults(String operand1, String operator, String operand2)
{
System.out.println("Performing "+
operand1+operator+operand2);
double op1=Double.parseDouble(operand1);
double op2=Double.parseDouble(operand2);
if(operator.equals("*"))
return ""+(op1*op2);
else if(operator.equals("/"))
return ""+(op1/op2);
else if(operator.equals("+"))
return ""+(op1+op2);
else if(operator.equals("-"))
return ""+(op1-op2);
else
return null;
}
public static void main(String[] args)
{
Infix fix=new Infix();
String expression="5-3*2*1/2+2";
System.out.println(expression+"="+fix.infix(expression));
}
}
Also, if u don't mind, is there a better, easier to understand way of coding this? (this is not as important as the grammar definition) I hope you understand my request :)

Math Expression Parser

I found the code of Math Expression Parser from Dreamincode Forum.
My question is, on that code I think everything is going all right, but when I had a testcase '(2(3+5)' , that was valid, whereas this test case is completely wrong
but if I give the test case '(3+5)2)' it was detect as non valid input.
Anyone knows why this is happening?
//enum for Operator "objects"
import java.util.*;
public enum Operator {
ADD("+", 1)
{
double doCalc(double d1, double d2) {
return d1+d2;
}
},
SUBTRACT("-",1)
{
double doCalc(double d1, double d2) {
return d1-d2;
}
},
MULTIPLY("*", 2)
{
double doCalc(double d1, double d2) {
return d1*d2;
}
},
DIVIDE("/",2)
{
double doCalc(double d1, double d2) {
return d1/d2;
}
},
STARTBRACE("(", 0)
{
double doCalc(double d1, double d2) {
return 0;
}
},
ENDBRACE(")",0)
{
double doCalc(double d1, double d2) {
return 0;
}
},
EXP("^", 3)
{
double doCalc(double d1, double d2) {
return Math.pow(d1,d2);
}
};
private String operator;
private int precedence;
private Operator(String operator, int precedence) {
this.operator = operator;
this.precedence = precedence;
}
public int getPrecedenceLevel() {
return precedence;
}
public String getSymbol() {
return operator;
}
public static boolean isOperator(String s) {
for(Operator op : Operator.values()) { //iterate through enum values
if (op.getSymbol().equals(s))
return true;
}
return false;
}
public static Operator getOperator(String s)
throws InvalidOperatorException {
for(Operator op : Operator.values()) { //iterate through enum values
if (op.getSymbol().equals(s))
return op;
}
throw new InvalidOperatorException(s + " Is not a valid operator!");
}
public boolean isStartBrace() {
return (operator.equals("("));
}
//overriding calculation provided by each enum part
abstract double doCalc(double d1, double d2);
}
//error to be thrown/caught in ProjectOne.java
class InvalidOperatorException extends Exception {
public InvalidOperatorException() {
}
public InvalidOperatorException(String s) {
super(s);
}
}
//reading in a string at doing the parsing/arithmetic
public static void main (String[] args) {
String input = "";
//get input
System.out.print("Enter an infix exp<b></b>ression: ");
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
try {
input = in.readLine();
}
catch (IOException e)
{
System.out.println("Error getting input!");
}
doCalculate(input);
}
// Input: user entered string
// Output: Display of answer
public static void doCalculate(String equation) {
//our stacks for storage/temp variables
Stack<Operator> operatorStack;
Stack<Double> operandStack;
double valOne, valTwo, newVal;
Operator temp;
//initalize
StringTokenizer tokenizer = new StringTokenizer(equation, " +-*/()^", true);
String token = "";
operandStack = new Stack();
operatorStack = new Stack();
try {
while(tokenizer.hasMoreTokens()){ //run through the string
token = tokenizer.nextToken();
if (token.equals(" ")) { //handles spaces, goes back up top
continue;
}
else if (!Operator.isOperator(token)){ //number check
operandStack.push(Double.parseDouble(token));
}
else if (token.equals("(")) {
operatorStack.push(Operator.getOperator(token));
}
else if (token.equals(")")) { //process until matching paraentheses is found
while (!((temp = operatorStack.pop()).isStartBrace())) {
valTwo = operandStack.pop();
valOne = operandStack.pop();
newVal = temp.doCalc(valOne, valTwo);
operandStack.push(newVal);
}
}
else { //other operators
while (true) { //infinite loop, check for stack empty/top of stack '('/op precedence
if ((operatorStack.empty()) || (operatorStack.peek().isStartBrace()) ||
(operatorStack.peek().getPrecedenceLevel() < Operator.getOperator(token).getPrecedenceLevel())) {
operatorStack.push(Operator.getOperator(token));
break; //exit inner loop
}
temp = operatorStack.pop();
valTwo = operandStack.pop();
valOne = operandStack.pop();
//calculate and push
newVal = temp.doCalc(valOne, valTwo);
operandStack.push(newVal);
}
}
}
}
catch (InvalidOperatorException e) {
System.out.println("Invalid operator found!");
}
//calculate any remaining items (ex. equations with no outer paraentheses)
while(!operatorStack.isEmpty()) {
temp = operatorStack.pop();
valTwo = operandStack.pop();
valOne = operandStack.pop();
newVal = temp.doCalc(valOne, valTwo);
operandStack.push(newVal);
}
//print final answer
System.out.println("Answer is: " + operandStack.pop());
}
This calculator does not work with implicit multiplication. you can use:
2((2+2)+1)
And see that it gives the wrong answer as opposed to:
2*((2+2)+1)
The false-positive expression you've used does not pass with explicit multiplication.
A quick for-the-lazy fix to add implicit multiplication would be something of that sort:
public static void doCalculate(String equation) {
// make it explicit:
System.out.println("Got:" + equation);
Pattern pattern = Pattern.compile("([0-9]+|[a-z\\)])(?=[0-9]+|[a-z\\(])");
Matcher m = pattern.matcher(equation);
System.out.println("Made it: "+ (equation = m.replaceAll("$1*")));
//our stacks for storage/temp variables
Stack<Operator> operatorStack;
Stack<Double> operandStack;
double valOne, valTwo, newVal;
Operator temp;
This is an attempt to capture implicit multiplication using regex and make it explicit.
It fixes all cases we've come up with.

Need help in implementing Java Algorithm on Postfix Evaluation

I've tried writing this code from scratch, coding, and running it but it just doesn't seem to work. This was assigned as lab work in class. The requirements are:
Implementing a postfix evaluation with the use of a stack and stack operations (user-defined).
I think the algorithm of my program is right, but it always gives me the wrong answer.
Here is my code.
public class StackApplication {
public static class Stack<T> {
private int top = 0;
private final static int stackMax=100;
// highest index of stk array
private Object[] stk = new Object[stackMax+1];
//Elements must be cast back.
public Stack() { // constructor
}
public boolean isEmpty(){
if (top==0) return true;
else return false;
}
public void push(T el) {
if(top==stackMax)
System.out.println("Stack push overflow error");
else top=top+1;
stk[top]=el;
}
public T pop(){
if(isEmpty()){
System.out.println("Stack push underflow error");
return null;
}
else top=top-1;
return(T)stk[top+1];
}
public T top(){
if(isEmpty()){
//System.out.println("Stack empty");
return null;
}
else return (T)stk[top];
}
}
public static boolean isOperator(char c){
return(c=='+' || c=='-' || c=='/' || c=='*' || c=='^');
}
public static double evaluate(double x, char o, double y) {
double result=0;
switch(o) {
case '+' : result=x+y; break;
case '-' : result=x-y; break;
case '*' : result=x*y; break;
case '/' : result=x/y; break;
case '^' : result=Math.pow(x, y); break;
default : break;
}
return result;
}
public static void main(String[] args) {
Scanner console=new Scanner(System.in);
Stack<Double> s=new Stack<Double>();
System.out.println("Input Postfix form to evaluate:");
String inp=console.nextLine();
char[] chararray=inp.toCharArray();
double b,a;
for(int i=0; i<chararray.length; i++) {
if(!isOperator(chararray[i]))
s.push((double)chararray[i]);
else {
b=s.pop();
a=s.pop();
double c=evaluate(a, chararray[i], b);
s.push(c);
}
}
System.out.println(" " +s.pop());
}
}
Sample Output:
Input Postfix form to evaluate:
23+ (Input)
101.0 (Output)
5.0 (Expected output)
The problem is here: s.push((double)chararray[i]);. You can't convert char to double this way. You are now taking the ascii code of 2 and 3.
50(ascii code of 2) + 51(ascii code of 3) = 101
Do it like this: s.push((double)(chararray[i] - '0'));
Your are doing the addition of the ASCII codes for 2 and 3, not of 2 and 3.
The code for 2 is 50 and for 3 is 51, so your out is 101, which is correct in this case.
When you push, push chararray[i]-'0'. This will solve your problem.

Categories