Re: Need help on a calculator project
Quote:
Originally Posted by
Speculant
Update, I want to now be able to be able to assign a value to any variable the user enters, and also implement the ^ (power) sign as a math possibility. Would hashtables still be optimal for assigning any variable the user enters, or would parallel arrays be better?
Right.. Let's go through, step by step how you would add a value to any variable the user types in.
1: Analyse the string for some combination of "^[a-zA-Z]=[0-9]+$". If you aren't familiar with regex, it makes life a lot easier for what you're doing.
So basically all i've said is scan a string for a letter, followed by an equals sign, followed by a number. So in your string, you find a letter. All you do is look to the right of the letter. If it's another letter, it's still part of the variable title. If it's an equals sign, you know it's an assignment operation. So there is only going to be one equals sign, so you keep looking to the right. Then you find some number. Keep looking too the right until it ceases to be a numeric value.
2: extract the variable title and value.
So now you've found where they are, you store them in some temporary variables. Next, and this bit is up to you, you can either do as Josah suggested and literally create the variables, or do as others have suggested and implement a hashmap. That is as far as im going though. The program is your own, and you should make decisions about how it runs. I hope this gets you on the right track :)
Re: Need help on a calculator project
Cool, that way you can't do e.g. xyz = 1+2 for several reasons; that solution is severly crippled.
kind regards,
Jos
Re: Need help on a calculator project
true, but if we, for example, capped variable names at one letter, then you could construct an array on the fly to store each variable name. then check what's going on on the other side of the equals sign, and if there's another operator, call a piece of code that will extract the addition operation from a string, and pass it the substring from the "=" onwards. Your way works nicely as well, and I think both of them are good solutions. I just posed one idea to get him going because I like how this guy is sticking to the same thread, not asking for us to just give him the answer and his explanations are really quite lucid :)
Re: Need help on a calculator project
Alright, I successfully implemented exponents (and exponents of exponents), for example, 2^2^2 gives the correct answer (16), and I think I am going to hold off on the assignment operator for now, my top priority now is figuring out how to implement double negatives. I want the program to be able to take, for example, --5-3+-3 and give -1 as an answer.
Here's what I have:
Calculator.java
Code:
import java.util.*;
public class Calculator
{
String expstring;
int cursor;
public Calculator()
{
expstring = null;
}
public Calculator(String instring)
{
expstring = instring;
cursor = 0;
}
public void setExpression(String estring)
{
expstring = estring;
cursor = 0;
}
public float assignmentOp(HashMap hashMap) //
{
cursor = 0;
float result = evalExp();
while (nextOperator('='))
{
char operator = getOperator();
float term = evalExp();
if (operator == '=') //used to append the term as a value to the appropriate key.
{
hashMap.put(String.valueOf(result), term);
}
else
System.err.println("Please enter a valid string to be used as a variable");
}
return result;
}
public float evalExp()
{
if (expstring == null)
{
System.err.println("There is no expression to evaluate.");
System.err.println("Call setExpression() before calling getResult().");
return 0;
}
float result = evalTerm();
while (nextOperator('+'))
{
char operator = getOperator();
float term = evalTerm();
if (operator == '+')
result = result + term;
else
System.err.println("Invalid operator: " + operator);
}
while (nextOperator('-'))
{
char operator = getOperator();
float term = evalTerm();
if (operator == '-')
result = result - term;
else
System.err.println("Invalid operator: " + operator);
}
return result;
}
private float evalTerm()
{
float result = calcExponent();
while (nextOperator('*'))
{
char operator = getOperator();
float term = calcExponent();
if (operator == '*')
result = result * term;
else
break;
}
while (nextOperator('/'))
{
char operator = getOperator();
float term = calcExponent();
if (operator == '/')
result = result / term;
else
break;
}
return result;
}
private float calcExponent()
{
float result = getOperand();
while (nextOperator('^'))
{
char operator = getOperator();
float term = getOperand();
if (operator == '^')
{
float result2 = 1;
for (short i = 0; i < term; i++)
result2 = result2 * result;
result = result2;
}
else
break;
}
return result;
}
private float getOperand()
{
if (cursor >= expstring.length())
return 0;
String opstring = "";
char nextchar = expstring.charAt(cursor);
if (nextchar == '-')
{
opstring = opstring + '-';
cursor++;
nextchar = expstring.charAt(cursor);
}
while (cursor < expstring.length() && !isOperator(nextchar))
{
opstring = opstring + nextchar;
cursor++;
if (cursor < expstring.length())
nextchar = expstring.charAt(cursor);
}
return Float.parseFloat(opstring);
}
private char getOperator()
{
char operator = expstring.charAt(cursor);
cursor++;
return operator;
}
private boolean nextOperator(char op)
{
if (cursor < expstring.length() && expstring.charAt(cursor) == op)
return true;
else
return false;
}
private boolean isOperator(char c)
{
String opset = "+*-/=^";
return (opset.indexOf(c) >= 0);
}
}
ExpressionDialog.java
Code:
import java.util.*;
import java.io.*;
class ExpressionDialog
{
Scanner keyreader;
Calculator calc;
PrintStream logfile;
HashMap hashMap = new HashMap(); //creates a new hashmap that will store the variable and the number as key/value pairs
public ExpressionDialog()
{
keyreader = new Scanner(System.in);
calc = new Calculator();
}
public void run()
{
String expression;
float result = 0;
showMenu();
expression = getNextExpression();
while(!expression.equals("quit"))
{
if (expression.equals("log off") && (logfile != null))
{
logfile.close();
}
else if (expression.equals("log"))
{
//Not very clean, prompt should be on the same line as the user input
//Also adds a space and => 0.0 at the start of the file, this isn't clean and ideally should be changed
System.out.println("Enter in a filename");
setLogFile(keyreader.next());
}
//prints the value of a key if it is entered into the prompt.
/*else if (expression.equals(""))
{
String next = keyreader.next();
System.out.println("=> " + hashMap.get(next));
}*/
else
{
calc.setExpression(expression);
try
{
result = calc.assignmentOp(hashMap); //passes the hashmap to assignmentOp
System.out.println("=> " + result);
if (logfile != null)
{
logfile.println(expression);
logfile.println("=> " + result);
}
}
catch (NumberFormatException e)
{
System.out.println("Incorrect entry");
}
}
expression = getNextExpression();
}
if (logfile != null)
logfile.close();
}
private String getNextExpression()
{
System.out.print("? ");
return keyreader.nextLine();
}
private void showMenu()
{
System.out.println("<expression> //Enter a simple arithmetic expression");
System.out.println("log <filename> //Turn on file logging to the specified output file");
System.out.println("log off //Turn file logging off");
System.out.println("quit //To terminate the program");
}
private void setLogFile(String filename)
{
try
{
logfile = new PrintStream(filename);
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
public static void main(String[] args)
{
ExpressionDialog dialog = new ExpressionDialog();
if (args.length > 0)
dialog.setLogFile(args[0]);
dialog.run();
}
}
I'm pretty sure all I would have to do is, in getOperand, keep scanning the line to see if the next character after the - is another -, and if it is, cancel out both - signs. I'm just not sure how to code it.
Re: Need help on a calculator project
Quote:
--5-3+-3 and give -1 as an answer.
How do you evaluate that? Where would you put the ()s?
Doing it this way:
-(-5-3)+(-3) gives 5
-(-5)-3+(-3) gives -1
Re: Need help on a calculator project
well, I want the program to evaluate it as --5 (which would be 5) minus 3 (which would be 2) plus a negative 3 (which would be -1)
Re: Need help on a calculator project
Correctly placed ()s help.
Re: Need help on a calculator project
oh, sorry. it would be -(-5)-3+(-3)
Re: Need help on a calculator project
Quote:
Originally Posted by
Speculant
oh, sorry. it would be -(-5)-3+(-3)
So literal numbers can be negative and you have a unary minus operator. If so, you can do silly things such as: -----5+----3
kind regards,
Jos
Re: Need help on a calculator project
Who gave you this program to work on? Are you in Comp Sci 161 at UND?
Btw, I don't have any issues with you hijacking this thread, as it is the same exact program you need help with.