I'm not sure where to post this, but the program does run as expected, i was just looking for input to where i may have taken a more difficult route.
It is intended to not be recursive because i couldn't quite wrap my head around the logic of the recursive form my teacher suggested.
The main objective is the order of operations part
There are 4 classes.
1- TheCalc - main class
2- Calculator - handles the the list that the equation turns into
3- Calculation - does the math work
4- Node - to make the string into a list
TheCalc:
import java.awt.BorderLayout; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JTextField; public class TheCalc extends JFrame { int BUTTON_COUNT = 20; int caretPos; static JPanel Outer; static JTextField InOut; static JPanel Buttons; static JButton[] TheButtons; TheCalc(){ setSize(250,200); Outer = new JPanel(new BorderLayout()); InOut = new JTextField(); Buttons = new JPanel(new GridLayout(5,4)); TheButtons = new JButton[BUTTON_COUNT]; for(int a = 0; a < BUTTON_COUNT; a++){ TheButtons[a] = new JButton(); Buttons.add(TheButtons[a]); switch(a){ case 0:TheButtons[a].setText("+"); TheButtons[a].addActionListener(new RegListener()); break; case 1:TheButtons[a].setText("-"); TheButtons[a].addActionListener(new RegListener()); break; case 2:TheButtons[a].setText("*"); TheButtons[a].addActionListener(new RegListener()); break; case 3:TheButtons[a].setText("/"); TheButtons[a].addActionListener(new RegListener()); break; case 4:TheButtons[a].setText("7"); TheButtons[a].addActionListener(new RegListener()); break; case 5:TheButtons[a].setText("8"); TheButtons[a].addActionListener(new RegListener()); break; case 6:TheButtons[a].setText("9"); TheButtons[a].addActionListener(new RegListener()); break; case 7:TheButtons[a].setText("("); TheButtons[a].addActionListener(new RegListener()); break; case 8:TheButtons[a].setText("4"); TheButtons[a].addActionListener(new RegListener()); break; case 9:TheButtons[a].setText("5"); TheButtons[a].addActionListener(new RegListener()); break; case 10:TheButtons[a].setText("6"); TheButtons[a].addActionListener(new RegListener()); break; case 11:TheButtons[a].setText(")"); TheButtons[a].addActionListener(new RegListener()); break; case 12:TheButtons[a].setText("1"); TheButtons[a].addActionListener(new RegListener()); break; case 13:TheButtons[a].setText("2"); TheButtons[a].addActionListener(new RegListener()); break; case 14:TheButtons[a].setText("3"); TheButtons[a].addActionListener(new RegListener()); break; case 15:TheButtons[a].setText("^"); TheButtons[a].addActionListener(new RegListener()); break; case 16:TheButtons[a].setText("0"); TheButtons[a].addActionListener(new RegListener()); break; case 17:TheButtons[a].setText("."); TheButtons[a].addActionListener(new RegListener()); break; case 18:TheButtons[a].setText("="); TheButtons[a].addActionListener(new CalculateListener()); break; case 19:TheButtons[a].setText("CLR"); TheButtons[a].addActionListener(new ClearListener()); break; } } Outer.add(InOut, BorderLayout.NORTH); Outer.add(Buttons, BorderLayout.CENTER); add(Outer); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setTitle("Algebraic Calculator"); } public class CalculateListener implements ActionListener{ public void actionPerformed(ActionEvent e){ Calculator Calc = new Calculator("(" + InOut.getText() + ")"); Calc.display(); if(Calc.legal == false){ InOut.setText(InOut.getText() + ":: ERROR :: CODE " + Calc.errorcode); } else{ Calc.Interpret(); InOut.setText(Double.toString(Calc.answer)); } Calc.head = null; } } public class RegListener implements ActionListener{ public void actionPerformed(ActionEvent e){ for(int a = 0; a < BUTTON_COUNT; a++){ if(e.getSource() == TheButtons[a]){ caretPos = InOut.getCaretPosition(); InOut.setText(new StringBuffer(InOut.getText()).insert(caretPos, TheButtons[a].getText()).toString()); InOut.setCaretPosition(caretPos+1); } } } } public class ClearListener implements ActionListener{ public void actionPerformed(ActionEvent e){ InOut.setText(""); } } public static void main(String[] args){ new TheCalc(); } }
Calculator:
public class Calculator { Node temp; static Node current; static Node head; static boolean broken; boolean legal; static int errorcode; static double answer; Calculator(String equation){ current = head; int id = 0; try{ while(id < equation.length()){ String nodevalue = ""; char tempchar = equation.charAt(id); if((tempchar >= '0' && tempchar <= '9')||tempchar == '.'){ while((id < equation.length() && equation.charAt(id) >= '0' && equation.charAt(id) <= '9')||equation.charAt(id) == '.' ){ nodevalue = nodevalue + equation.charAt(id); id++; } temp = new Node(null, true, Double.parseDouble(nodevalue), ' '); if(head == null){ head = temp; } else{ current.next = temp; } current = temp; } else{ temp = new Node(null, false, 0.0, equation.charAt(id)); if(head == null){ head = temp; } else{ current.next = temp; } current = temp; id++; } } } catch(NumberFormatException e){ broken = true; } id = 0; legal = checkLegality(); } public static boolean checkLegality(){ /* * ERROR CODES: * 1. Too many points in an int * 2. Two ops next to each other * 3. Two integers next to each other * 4. No int after operator * 5. No op between int and parentheses * 6. Incorrect number of parenthesis */ if(broken == true){ broken = false; errorcode = 1; return false; } current = head; while(current != null){ if(current.ifnum == true){ if(current.next == null){ break; } else if(current.next.ifnum == true){ errorcode = 3; return false; } else if(current.next.ifnum == false){ if(current.next.op == '('){ errorcode = 5; return false; } } } else if(current.ifnum == false){ if(current.op == ')'){ if(current.next == null){ break; } else if(current.next.ifnum == true){ errorcode = 5; return false; } else if(current.next.op == '('){ errorcode = 2; return false; } } else if(current.op == '+'||current.op == '-'||current.op == '*'||current.op == '/'||current.op =='^'){ if(current.next == null){ errorcode = 4; return false; } else if(current.next.op == ')'||current.next.op == '+'||current.next.op == '-'||current.next.op == '/'||current.next.op == '*'||current.next.op == '^'){ errorcode = 2; return false; } } } current = current.next; } current = head; int openp = 0; int closedp = 0; while(current!=null){ if(current.op == '('){ openp++; } else if(current.op == ')'){ closedp++; } current = current.next; } if(openp == closedp){ return true; } else{ errorcode = 6; return false; } } public static void Interpret(){ Calculation math = null; Node start = null; Node end = null; while(head.next != null){ current = head; while(current.op != ')'){ if(current.op == '('){ start = current; } current = current.next; } end = current; current = start.next; while(start.next.next != end){ math = new Calculation(current, current.next, current.next.next, current.next.next.next); if(math.good){ current.removeLastOp(math); current = start.next; display(); } else{ current = math.intb; } } start.setValues(end.next, true, start.next.number, ' '); } answer = head.number; } public static void display(){ Node remember = current; current = head; while(current!=null){ if(current.ifnum == true){ System.out.print(current.number); } else if(current.ifnum == false){ System.out.print(current.op); } current = current.next; } System.out.println(""); current = remember; } }
Calculation:
public class Calculation { static Node inta; static Node intb; static Node opa; static Node opb; static boolean good; static double answer; Calculation(Node a, Node b, Node c, Node d){ setValues(a,b,c,d); } public static void setValues(Node a, Node b, Node c, Node d){ inta = a; opa = b; intb = c; opb = d; good = checkInOrder(); answer = getAnswer(); } public static boolean checkInOrder(){ if(opa.order < opb.order){ return false; } else{ return true; } } public static double getAnswer(){ switch(opa.op){ case '+': return inta.number + intb.number; case '-': return inta.number - intb.number; case '*': return inta.number * intb.number; case '/': return inta.number / intb.number; case '%': return inta.number % intb.number; case '^': return Math.pow(inta.number, intb.number); default: return 1; } } }
Node:
public class Node { Node next; boolean ifnum; double number; char op; int order; Node(Node a, boolean b, double c, char d){ setValues(a,b,c,d); } public void setValues(Node a, boolean b, double c, char d){ next = a; ifnum = b; number = c; op = d; switch(d){ case '+': case '-': order = 1;break; case '*': case '/': case '%': order = 2;break; case '^': order = 3;break; case ')': order = 0;break; case '(': order = 0;break; } } public void removeLastOp(Calculation math){ number = math.answer; next = math.opb; } }
I think i do a lot of checks that i don't need to do, but oh well, i don't think its too hard to follow but i probably should have put some comments in there
Thanks!
btw, if theres a better section ill delete and repost, i'm new so im a little unsure
This is the system output for '4+4/4'
(4.0+4.0/4.0)
(4.0+1.0)
(5.0)