I have started to learn Java and I need your critique for my first program. It is an interpreter that can calculate any expression including abs()
, sqrt()
, min()
, max()
, round()
and pow()
.
What can you say about this? Are there any code defects or pointless comments?
Main
class
import java.io.*;
public class Main {
static boolean Error=false;
public static void main(String args[]) throws Exception{
System.out.println("Type an expression to calculate \n" +
"abs(x) function returns absolute value of x\n" +
"sqrt(x) function returns square root of value x\n" +
"min(x,y,…) function returns a minimum value between x,y,...\n" +
"max(x,y,…) function returns a maximum value between x,y,...\n" +
"round(x) function returns a round value of x\n" +
"pow(x,y) function returns an exponentiation of x,y\n" +
"Type \"exit\" to exit");
while (true){
BufferedReader read = new BufferedReader(new InputStreamReader(System.in));
String stringForProcessing =read.readLine(); //Input a string to work with it
String output= Calculating.calculating(stringForProcessing); //Calculating
System.out.println(output);//Output
Error=false;
}
}
}
Calculating
class
import java.lang.Math;
import java.util.ArrayList;
public class Calculating {
static String calculating(String workingString){
ArrayList<String> separatedString = new ArrayList<>();
int Position=0;
boolean Negative=false;
if(Main.Error){ //return error report
return(workingString);
}
while(Position<workingString.length()){ //reducing spaces
if(workingString.charAt(Position)==' '){
while (((Position)<workingString.length())
&&(workingString.charAt(Position)==' ')){
Position++;
}
}
else if (workingString.charAt(Position)=='-'&&(Position==0 //checking value for negativity
|| workingString.charAt(Position-1)=='-'
|| workingString.charAt(Position-1)=='+'
|| workingString.charAt(Position-1)=='*'
|| workingString.charAt(Position-1)=='/')){
Negative=true;
Position++;
}
else if ((workingString.charAt(Position)=='-' //checking for repeating operators
|| workingString.charAt(Position)=='+'
|| workingString.charAt(Position)=='*'
|| workingString.charAt(Position)=='/')
&&(Position==0
|| workingString.charAt(Position-1)=='-'
|| workingString.charAt(Position-1)=='+'
|| workingString.charAt(Position-1)=='*'
|| workingString.charAt(Position-1)=='/')){
Main.Error=true;return("Error: two or more operators in a row");
}
separatedString.add(Character.toString(workingString.charAt(Position)));
if (workingString.charAt(Position)=='('){ //Creating bracer stack to parse
int BrcrStack=1;
String Temp="";
while (((Position+1)<workingString.length())){
switch (workingString.charAt(Position+1)){
case '(':BrcrStack++;break;
case ')':BrcrStack--;break;
}
Position++;
if(BrcrStack!=0){
Temp+=workingString.charAt(Position);
}
else {break;}
}
if(BrcrStack!=0){
Main.Error=true;return("Error: missing \")\"");
}
separatedString.set(separatedString.size()-1, calculating(Temp));
}
else if (Character.isDigit(workingString.charAt(Position))){ //Bolting numbers
while (((Position+1)<workingString.length())&&(Character.isDigit(workingString.charAt(Position+1))
|| workingString.charAt(Position+1)=='.') ){
separatedString.set(separatedString.size()-1,
separatedString.get(separatedString.size()-1)+workingString.charAt(Position+1));
Position++;
}
try {
Float.valueOf(separatedString.get(separatedString.size()-1));}
catch(Exception e){
Main.Error=true;return("Error: multiple points");
}
if(Negative){ //Negate parameter
separatedString.set(separatedString.size()-1,Float.toString(-(Float.valueOf(separatedString.get(separatedString.size()-1)))));
Negative=false;
}
}
else if (Character.isAlphabetic(workingString.charAt(Position))){ //Bolting functions
while (((Position+1)<workingString.length())
&&(Character.isAlphabetic(workingString.charAt(Position+1))) ){
separatedString.set(separatedString.size()-1,
separatedString.get(separatedString.size()-1)+workingString.charAt(Position+1));
Position++;
}
switch (separatedString.get(separatedString.size()-1)){ //Checking functions
case "abs":break;
case "sqrt":break;
case "min":break;
case "max":break;
case "round":break;
case "pow":break;
case "exit":System.exit(0);
default: {
Main.Error=true;return("Error: unknown function \""+separatedString.get(separatedString.size()-1)+"\"");
}
}
if ((Position+1)==workingString.length()||workingString.charAt(Position+1)!='(') //Parsing function parameters
{
Main.Error=true;return("Error: missing \"(\" after "+"\""+separatedString.get(separatedString.size()-1)+"\" "+ "function");
}
ArrayList<String> Temp = new ArrayList<>();
int BrcrStack=1;
Temp.add("");
while (((Position+2)<workingString.length())){
switch (workingString.charAt(Position+2)){
case '(':BrcrStack++;break;
case ')':BrcrStack--;break;
case ',': if (BrcrStack==1){Temp.add("");Position++;continue;}break;
}
Position++;
if(BrcrStack!=0){Temp.set(Temp.size()-1,Temp.get(Temp.size()-1)+Character.toString(workingString.charAt(Position+1)));}
else {break;}
}
if(BrcrStack!=0){
Main.Error=true;return("Error: missing \")\"");}
Position++;
float FuncArr[]=new float[Temp.size()];
for (int i=0;i<Temp.size();i++){
Temp.set(i, Calculating.calculating(Temp.get(i)));
if (Temp.get(i).length()==0){
Main.Error=true;return("Error: missing expression");}
FuncArr[i]=Float.valueOf(Temp.get(i));
}
switch (separatedString.get(separatedString.size()-1)){ //Calculating functions
case "abs":if (FuncArr.length==1) {
separatedString.set(separatedString.size()-1,Float.toString(Math.abs(FuncArr[0])));}
else {
Main.Error=true;return("Error: \"abs\" function needs only one argument");}break;
case "sqrt":if (FuncArr.length==1) {
double a=FuncArr[0];
separatedString.set(separatedString.size()-1,Double.toString(Math.sqrt(a)));}
else {
Main.Error=true;return("Error: \"sqrt\" function needs only one argument");}break;
case "min":separatedString.set(separatedString.size()-1,Float.toString(Min(FuncArr))) ;break;
case "max":separatedString.set(separatedString.size()-1,Float.toString(Max(FuncArr))) ;break;
case "round":if (FuncArr.length==1) {
separatedString.set(separatedString.size()-1,Float.toString(Math.round((FuncArr[0]))));}
else {
Main.Error=true;return("Error: \"round\" function needs only one argument");}break;
case "pow":if (FuncArr.length==2) {
separatedString.set(separatedString.size()-1,Double.toString(Math.pow(FuncArr[0],FuncArr[1])));}
else {
Main.Error=true;return("Error: \"pow\" function needs only two arguments");}break;
}
}
Position++;
}
ArrayList<String> ResultArr = new ArrayList<>();
if(Negative){ //Negate parameter
separatedString.set(separatedString.size()-1,Float.toString(-(Float.valueOf(separatedString.get(separatedString.size()-1)))));
}
ArrayList<String> Stack = new ArrayList<>();
int i=0;
while (i<separatedString.size()){ //Converting expression to postfix notation
if (separatedString.get(i).length()==1&&(separatedString.get(i).charAt(0)=='+'||separatedString.get(i).charAt(0)=='-'||separatedString.get(i).charAt(0)=='/'||separatedString.get(i).charAt(0)=='*')){
if(Stack.size()==0){
Stack.add(separatedString.get(i));
}else {
if ((separatedString.get(i).charAt(0) == '+' || separatedString.get(i).charAt(0) == '-') && (Stack.get(Stack.size() - 1).charAt(0) == '*' || Stack.get(Stack.size() - 1).charAt(0) == '/')) {
Stack.add(separatedString.get(i));
} else {
Stack.add(separatedString.get(i));
Stack.add(separatedString.get(i+1));
i++;
while (Stack.size() > 0) {
ResultArr.add(Stack.get(Stack.size()-1));
Stack.remove(Stack.size() - 1);
}
}
}
}
else{
ResultArr.add(separatedString.get(i));
}
i++;
}
while (Stack.size() > 0) {
ResultArr.add(Stack.get(Stack.size()-1));
Stack.remove(Stack.size() - 1);
}
i=0;
while (ResultArr.size()>1){ //Calculating postfix expression
if (ResultArr.get(i).length()==1&&(ResultArr.get(i).charAt(0)=='+'||ResultArr.get(i).charAt(0)=='-'||ResultArr.get(i).charAt(0)=='/'||ResultArr.get(i).charAt(0)=='*')){
switch (ResultArr.get(i).charAt(0)){
case '+':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))+Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
case '-':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))-Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
case '*':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))*Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
case '/':ResultArr.set(i-2,Float.toString(Float.valueOf(ResultArr.get(i-2))/Float.valueOf(ResultArr.get(i-1))));ResultArr.remove(i);ResultArr.remove(i-1);break;
}
i=0;
}
i++;
}
String Result="";
for (String aResultArr : ResultArr) {
Result += aResultArr;
}
if (Float.valueOf(Result)==Math.floor(Float.valueOf(Result))){
Result=Integer.toString(Math.round(Float.valueOf(Result)));
}
return Result;
}
static float Min(float Arr[]){
float Min=Arr[0];
for (int i=1;i<Arr.length;i++){
if (Arr[i]<Min){Min=Arr[i];
}
}
return Min;
}
static float Max(float Arr[]){
float Max=Arr[0];
for (int i=1;i<Arr.length;i++){
if (Arr[i]>Max){Max=Arr[i];
}
}
return Max;
}
}