making a calculator in java - java

i have no idea why i am not getting the expected results! I have written the expected result in the end. Alright, i have two classes: CalculatorEngine and CalculatorInput, the former calculates while the latter gives a line mode interface. The code for CalculatorEngine goes like this, nothing fancy:
public class CalculatorEngine {
int value;
int keep;
int toDo;
void binaryOperation(char op){
keep = value;
value = 0;
toDo = op;
}
void add() {binaryOperation('+');}
void subtract() {binaryOperation('-');}
void multiply() {binaryOperation('*');}
void divide() {binaryOperation('/');}
void compute() {
if (toDo == '+')
value = keep + value;
else if (toDo == '-')
value = keep - value;
else if (toDo == '*')
value = keep * value;
else if (toDo == '/')
value = keep/value;
keep = 0;
}
void clear(){
value = 0;
keep = 0;
}
void digit(int x){
value = value*10 + x;
}
int display(){
return (value);
}
CalculatorEngine() {clear();} //CONSTRUCTOR METHOD!
}
And the code for CalculatorInput goes like this:
import java.io.*;
public class CalculatorInput {
BufferedReader stream;
CalculatorEngine engine;
CalculatorInput(CalculatorEngine e) {
InputStreamReader input = new InputStreamReader(System.in);
stream = new BufferedReader(input);
engine = e;
}
void run() throws Exception {
for (;;) {
System.out.print("[" +engine.display()+ "]");
String m = stream.readLine();
if (m==null) break;
if (m.length() > 0) {
char c = m.charAt(0);
if (c == '+') engine.add();
else if (c == '*') engine.multiply();
else if (c == '/') engine.divide();
else if (c == '-') engine.subtract();
else if (c == '=') engine.compute();
else if (c == '0' && c <= '9') engine.digit(c - '0');
else if (c == 'c' || c == 'C') engine.clear();
}
}
}
public static void main(String arg[]) throws Exception{
CalculatorEngine e = new CalculatorEngine();
CalculatorInput x = new CalculatorInput(e);
x.run();
}
}
I expect the answer to be like this:
[0]1
[1]3
[13]+
[0]1
[1]1
[11]=
[24]
BUT i am getting this:
[0]1
[0]3
[0]+
[0]1
[0]1
[0]+
[0]
Seems like digit function isn't working properly. Help!

Change this:
if (c == '0' && c <= '9')
To this:
if (c >= '0' && c <= '9')
Otherwise, it will only be true when c is '0'.

else if (c == '0' && c <= '9') engine.digit(c - '0');
if c not equals 0 its false..

Related

Java - Prefix to Postfix using recursion

so I am in the middle of a data structures course and we have been tasked with making a recursive solution to a prefix (-+ABC) problem and converting it into a postfix (AB+C-) solution. I feel like I'm 70% there...just missing that little something.
The outputString is then returned and written to a .txt file. I know this part works due to past labs I have worked with.
The code provided returns BCBCABCBCBCABC+ABC when it should in theory return AB+C-
public static boolean operator(char o) {
return o == '+' || o == '-' || o == '*' || o == '/' || o == '$';
}
public static String preToPost(String s) {
char[] c = s.toCharArray();
// System.out.println(c);
char ch = c[0];
//System.out.println(ch);
char[] cMinusFront = new char[s.length() - 1];
for (int i = 0, k = 0; i < c.length; i++) {
if (i == 0) {
continue;
}
cMinusFront[k++] = c[i];
}
s = String.valueOf(cMinusFront);
System.out.println(s);
String a;
String b;
String outputString = null;
if (s.length() == 1) {
return outputString;
}
if (operator(ch)) {
a = preToPost(s);
} else {
a = s.substring(0, 0);
}
if (operator(ch)) {
b = preToPost(s);
} else {
b = s.substring(0, 0);
}
outputString = a;
outputString = outputString.concat(b);
outputString = outputString.concat(String.valueOf(cMinusFront));
return outputString;
}
Try this.
static boolean isOperator(char ch) {
return ch == '+' || ch == '-' || ch == '*' || ch == '/';
}
static String preToPost(StringReader input) throws IOException {
int ch = input.read();
if (ch == -1)
return "";
else if (isOperator((char)ch))
return preToPost(input) + preToPost(input) + (char)ch;
else
return "" + (char)ch;
}
static String preToPost(String input) throws IOException {
return preToPost(new StringReader(input));
}
public static void main(String[] args) throws IOException {
System.out.println(preToPost("*-+ABC"));
}
output:
AB+C-*

constructor in class cannot be applied to given types; found: java.lang.String,char reason: actual and formal argument lists differ in length

So my code for a calculator app i'm working on keeps giving me this error.
Error:(18, 36) java: constructor CalculationEngine in class
CalculationEngine cannot be applied to given types; required:
java.lang.String found: java.lang.String,char reason: actual and
formal argument lists differ in length
Here is the ConsoleApp class with the error
public class CalculatorConsoleApp {
private static final String EXIT_OPERATOR = "c";
public static void main(String[] args) {
System.out.printf("Welcome to the %s!\nPlease enter a one-operator expression to evaluate, or `%s` to exit.\n", CalculatorConstants.APP_NAME, EXIT_OPERATOR);
Scanner scanner = new Scanner(System.in);
String input;
// main loop
while(!(input = (scanner.nextLine())).equalsIgnoreCase(EXIT_OPERATOR)) {
char lastOperation = CalculatorConstants.NO_OPERATOR;
try {
CalculationEngine engine = new CalculationEngine(input,lastOperation);
System.out.printf("%.2f\n", engine.result);
} catch(Exception e) {
e.printStackTrace();
System.out.println(CalculatorConstants.BAD_NUMBER_MESSAGE);
}
}
System.out.println("Good bye!");
}
}
and the engine the corresponds to the ConsoleApp class
public class CalculationEngine {
public double result;
public CalculationEngine(String input) {
result = this.evaluateExpression(input);
}
private double evaluateExpression(String input) {
char[] tokens = input.toCharArray();
Stack<Double> values = new Stack<>();
Stack<Character> operations = new Stack<>();
for(int i = 0; i < tokens.length; i++) {
char token = tokens[i];
// skip whitespace
if(token == ' ')
continue;
if((token >= '0' && token <= '9') || token == CalculatorConstants.DECIMAL || (token == CalculatorConstants.SUBTRACTION_OPERATOR && ((i > 0 && isOperator(tokens[i-1]) || (i == 0))))) {
StringBuffer buffer = new StringBuffer();
while(i < tokens.length && ((tokens[i] >= '0' && tokens[i] <= '9') || tokens[i] == '.' || (token == CalculatorConstants.SUBTRACTION_OPERATOR && ((i > 0 && isOperator(tokens[i-1]) || (i == 0)))))) {
buffer.append(tokens[i++]);
}
if(buffer.toString().equals(".")) {
values.push(0.0);
} else {
values.push(Double.parseDouble(buffer.toString()));
}
i--;
} else if(
token == CalculatorConstants.ADDITION_OPERATOR ||
token == CalculatorConstants.SUBTRACTION_OPERATOR ||
token == CalculatorConstants.MULTIPLICATION_OPERATOR ||
token == CalculatorConstants.DIVISION_OPERATOR) {
while(!operations.empty() && hasPrecedence(tokens[i], operations.peek()))
values.push(applyOperation(operations.pop(), values.pop(), values.pop()));
operations.push(tokens[i]);
}
}
while(!operations.empty())
values.push(applyOperation(operations.pop(), values.pop(), values.pop()));
if(input.trim().length() == 1 && operations.size() == 1) {
return 0.0;
} else {
return values.pop();
}
}
private boolean isOperator(char operator) {
return (operator == CalculatorConstants.ADDITION_OPERATOR) || (operator == CalculatorConstants.SUBTRACTION_OPERATOR) || (operator == CalculatorConstants.MULTIPLICATION_OPERATOR) || (operator == CalculatorConstants.DIVISION_OPERATOR);
}
private double applyOperation(char operation, double num2, double num1) {
if (operation == CalculatorConstants.ADDITION_OPERATOR) {
return num1 + num2;
} else if (operation == CalculatorConstants.SUBTRACTION_OPERATOR) {
return num1 - num2;
} else if (operation == CalculatorConstants.MULTIPLICATION_OPERATOR) {
return num1 * num2;
} else if (operation == CalculatorConstants.DIVISION_OPERATOR) {
return num1 / num2;
}
return 0;
}
private boolean hasPrecedence(char op1, char op2) {
return (op1 == CalculatorConstants.ADDITION_OPERATOR || op2 ==
CalculatorConstants.SUBTRACTION_OPERATOR) && (op1 ==
CalculatorConstants.MULTIPLICATION_OPERATOR || op2 ==
CalculatorConstants.DIVISION_OPERATOR);
}
}
Your class CalculationEngine does not have constructor CalculationEngine(String, char). It just has CalculationEngine(String) only
Your statement:
CalculationEngine engine = new CalculationEngine(input,lastOperation);
Your current constructor:
public CalculationEngine(String input) {
result = this.evaluateExpression(input);
}

Invalid Identifier when using ArrayList<Character>

I am trying to finish this program for a homework assignment and This is the only thing not working. I get an expected error on this line:
System.out.println(myChars.equals(complement));
Here is my code
public class WCpalindrome {
private static char[] dna = {'A', 'C', 'T', 'G'};
private static ArrayList<Character> myChars = new ArrayList<Character>();
private static ArrayList<Character> reverse = new ArrayList<Character>();
private static ArrayList<Character> complement = new ArrayList<Character>();
public static char toUpperCase(char c) {
if (c == 'A' || c == 'a') {
return 'A';
} else if (c == 'T' || c == 't') {
return 'T';
} else if (c == 'C' || c == 'c') {
return 'C';
}
return 'G';
}
public static char getComplement(char c) {
if (c == 'A' || c == 'a') {
return 'T';
} else if (c == 'T' || c == 't') {
return 'A';
} else if (c == 'C' || c == 'c') {
return 'G';
}
return 'C';
}
public static void main(String[] args) {
char current;
int i = 0;
//Get the input sequence
while (StdIn.hasNextChar()) {
current = StdIn.readChar();
current = toUpperCase(current);
myChars.add(current);
StdOut.println(myChars.get(i));
i++;
}
System.out.println();
//Reverse the sequence
int k = 0;
int size = myChars.size() - 1;
for (int j = size-1; j >= 0; j--) {
current = myChars.get(j);
StdOut.println(current);
reverse.add(k, current);
k++;
}
System.out.println();
//Complement the reversed sequence
int n = 0;
size = myChars.size() - 1;
for (n = 0; n < size; n++) {
current = reverse.get(n);
complement.add(getComplement(current));
StdOut.println(complement.get(n));
}
}
//Prints true if the original equals the complement of the reversal
//else it prints false
System.out.println(myChars.equals(complement));
}
The line you are talking about is not inside any method. I think you want to move it inside your main method.
You have place the statement System.out.println(...); outside main(). Shift it up 3 lines. It is now at the level where method and field declarations are expected.
Also the equals will always return false as array instances do not compare there inside elements.
One might useArrays.equals` but you might simply use:
System.out.println(new String(myChars).equals(new String(complement)));
System.out.println(myChars.equals(complement));
outside of main method.
this should be in end
}
//Prints true if the original equals the complement of the reversal
//else it prints false
System.out.println(myChars.equals(complement));
}
}

stack implementation issue / not printing certain characters

I'm attempting to write an infix to postfix calculator. I am reading from a file that contains:
(4>3)+(3=4)+2
When i run my code, i should be getting a string containing the postfix notation of the input,
however i get absolutely nothing. my code doesnt seem to be reaching the final print statement. also when i modidy the code to get it to at least print(although the notation is incorrect) it only prints the numbers and not the operators ( +, -, &, etc). I cannot figure out why this is happening! i labeled in the code below where the print statement is:
public static void main(String[] args) {
readMathFile();
}
static String PF = "";
public static void postfix(char c, myStack s, myQueue q) {
if (c == '0' || c == '1' || c == '2' || c == '3' || c == '4' ||
c == '5' || c == '6' || c == '7' || c == '8' || c == '9') {
String cc = Character.toString(c);
PF.concat(cc);
} else if(c == '!' || c == '*' || c == '/' || c == '+' || c == '-' ||
c == '<' || c == '>' || c == '=' || c == '&' || c == '|') {
if(s.isEmpty())
s.push(c);
else {
char top = s.peek();
while ((precedence(top) > precedence(c)) && !s.isEmpty()) {
String cd = Character.toString(s.pop());
PF.concat(cd);
}
s.push(c);
}
}
}
public static myStack s;
public static myQueue q;
public static int i = 1;
// the file reading code was borrowed from:
// http://www.java2s.com/Code/Java/File-Input-Output/Readfilecharacterbycharacter.htm
public static void readMathFile() {
s = new myStack();
q = new myQueue();
File file = new File("test.txt");
if (!file.exists()) {
System.out.println(file + " does not exist.");
return;
}
if (!(file.isFile() && file.canRead())) {
System.out.println(file.getName() + " cannot be read from.");
return;
}
try {
FileInputStream fis = new FileInputStream(file);
char current;
// in this while loop is where all of the reading happens
while (fis.available() > 0) {
current = (char) fis.read();
//readMath(current, s, q);
postfix(current, s, q);
}
if(fis.available() == 0) {
char x = s.pop();
while(!s.isEmpty()) {
//q.enqueue(s.pop());
String ce = Character.toString(s.pop());
PF.concat(ce);
}
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("\n\n"+PF); // <----CODE NEVER REACHES THIS POINT! (and when i modify so it does, it will not print the operators!)
}

Reading in text file gives ArrayIndexOutOfBoundsException

I am attempting to read this .txt file into my program (as an improvement over manual input) and i am having trouble converting my methods to accept the input txt file. i get a arrayindexoutofboundsexception on line "infix[--pos]='\0';"
class Functions {
void postfix(char infix[], char post[]) {
int position, und = 1;
int outposition = 0;
char topsymb = '+';
char symb;
Stack opstk = new Stack();
opstk.top = -1;
for (position = 0; (symb = infix[position]) != '\0'; position++) {
if (isoperand(symb))
post[outposition++] = symb;
else {
if (opstk.isempty() == 1)
und = 1;
else {
und = 0;
topsymb = opstk.pop();
}
while (und == 0 && precedence(topsymb, symb) == 1) {
post[outposition++] = topsymb;
if (opstk.isempty() == 1)
und = 1;
else {
und = 0;
topsymb = opstk.pop();
}
}// end while
if (und == 0)
opstk.push(topsymb);
if (und == 1 || (symb != ')'))
opstk.push(symb);
else
topsymb = opstk.pop();
}// end else
}// end for
while (opstk.isempty() == 0)
post[outposition++] = opstk.pop();
post[outposition] = '\0';
}// end postfix function
int precedence(char topsymb, char symb) {
/* check precedence and return 0 or 1 */
if (topsymb == '(')
return 0;
if (symb == '(')
return 0;
if (symb == ')')
return 1;
if (topsymb == '$' && symb == '$')
return 0;
if (topsymb == '$' && symb != '$')
return 1;
if (topsymb != '$' && symb == '$')
return 0;
if ((topsymb == '*' || topsymb == '/') && (symb != '$'))
return 1;
if ((topsymb == '+' || topsymb == '-') && (symb == '-' || symb == '+'))
return 1;
if ((topsymb == '+' || topsymb == '-') && (symb == '*' || symb == '/'))
return 0;
return 1;
} /* end precedence function */
private boolean isoperand(char symb) {
/* Return 1 if symbol is digit and 0 otherwise */
if (symb >= '0' && symb <= '9')
return true;
else
return false;
}/* end isoperand function */
}
public class Driver {
public static void main(String[] args) throws IOException {
Functions f = new Functions();
char infix[] = new char[80];
char post[] = new char[80];
int pos = 0;
char c;
System.out.println("\nEnter an expression is infix form : ");
try {
BufferedReader in = new BufferedReader(new FileReader("infix.txt"));
String str;
while ((str = in.readLine()) != null) {
infix = str.toCharArray();
}
in.close();
} catch (IOException e) {
}
infix[--pos] = '\0';
System.out.println("The original infix expression is : ");
for (int i = 0; i < pos; i++)
System.out.print(infix[i]);
f.postfix(infix, post);
System.out.println("\nThe postfix expression is : ");
for (int i = 0; post[i] != '\0'; i++)
System.out.println(post[i]);
}
}
Do should never ever do like this:
try {
...
} catch (IOException e) {
}
You loose some essential information about your code-running.
At lease you should print the stack trace to follow the investigation:
e.printStackTrace();
You may have a FileNotFound exception.
In addition you try to index your array to -1 in infix[--pos], pos is set to 0 before this statement.
1) Totally aside, but I think line in main should read:System.out.println("\nEnter an expression in infix form : ");
2) As well, i agree about the catch statement. You already have narrowed it down to being an IOExcpetion, but you can find so much more info out by printing wither of the following inside the catch
System.err.println(e.getMessage()); or e.printStackTrace()
Now to answer your question. You are initializing pos to the value 0, but the you are doing a PREINCREMENT on the line infix[--pos] = '\0'; so pos becomes -1 (clearly outside the scope of the array bounddaries).
I think you want to change that to a post increment infix[pos--] = '\0';. Perhaps?
And yes, your code DOES Look like C...

Categories

Resources