I read about a coding style where not one variable is changed. Everything must stay constant. I don't remember what it's called, but it's the bomb. I never realized this little project would be so easy.
Here is a 98 line calculator that supports ()^*/+-. If you find a bug, please don't hesitate to comment. It doesn't handle invalid input well and forgets to loop, keeping the code short. You'll get a bunch of debug output and the result should be after RESULT.
Now to the main question: Did I do this right?
Other questions: Could anything be better? Is there anything wrong with it?
package jcalculator;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final String line = scanner.nextLine();
System.out.println("RESULT: "+parentheses(line));
}
static String parentheses(final String arg)
{
System.out.println("parent: "+arg);
if (arg.indexOf('(') < 0) return ""+math(arg);
final int offset0 = arg.lastIndexOf("(");
final int offset1 = next_of(offset0, arg, ')', +1);
try {
if (arg.charAt(offset0-1) != '*')
return parentheses(arg.substring(0, offset0) +
"*" +
arg.substring(offset0));
} catch (Exception e) {} // EOL
try {
if (arg.charAt(offset1+1) != '*')
return parentheses(arg.substring(0, offset1+1) +
"*" +
arg.substring(offset1+1));
} catch (Exception e) {} // EOL
return parentheses(arg.substring(0, offset0) +
math(arg.substring(offset0+1, offset1)) +
arg.substring(offset1+1));
}
static int next_of(
final int ret,
final String string,
final char find_char,
final int increment)
{
if (string.charAt(ret) != find_char)
return next_of(ret+increment, string, find_char, increment);
else return ret;
}
static int last_integer(
final int ret,
final String string,
final int increment)
{
try {
if (string.charAt(ret) == '.')
return last_integer(ret+increment, string, increment);
Integer.parseInt(""+string.charAt(ret));
return last_integer(ret+increment, string, increment);
} catch (Exception e) {
return ret + -increment;
}
}
static float math(final String arg) {
System.out.println("math: "+arg);
return Float.parseFloat(math_do(math_do(math_do(math_do(math_do( arg,
'^'), '*'), '/'), '+'), '-'));
}
static String math_do(final String arg, char operator) {
System.out.println("math_do: "+arg+" operator: "+operator);
if (arg.indexOf(operator) < 0) return arg;
else {
int middle = arg.indexOf(operator);
int left = last_integer(middle-1, arg, -1);
int right = last_integer(middle+1, arg, +1);
float a = Float.parseFloat(arg.substring(left, middle));
float b = Float.parseFloat(arg.substring(middle+1, right+1));
if (operator == '^') return math_do(arg.substring(0, left) +
Math.pow(a, b) +
arg.substring(right+1, arg.length()), operator);
if (operator == '*') return math_do(arg.substring(0, left) +
(a*b) +
arg.substring(right+1, arg.length()), operator);
if (operator == '/') return math_do(arg.substring(0, left) +
(a/b) +
arg.substring(right+1, arg.length()), operator);
if (operator == '+') return math_do(arg.substring(0, left) +
(a+b) +
arg.substring(right+1, arg.length()), operator);
if (operator == '-') return math_do(arg.substring(0, left) +
(a-b) +
arg.substring(right+1, arg.length()), operator);
System.exit(1); // fatal
return "";
}
}
}