English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Programma di calcolatrice in 200 righe di codice Java

Ho trovato un piccolo programma di calcolatrice che avevo scritto all'università, con un'interfaccia grafica, che può visualizzare graficamente l'albero grammaticale dell'espressione, hahah;)

Solo 200 righe di codice Java, in grado non solo di calcolare addizione, sottrazione, moltiplicazione e divisione, ma anche di abbinare parentesi tonde~

Commento sul codice:

Dalla colorazione semplice dell'interfaccia all'indicazione di errori intuitivi, tutto riflette l'idea di progettazione "esperienza utente" al primo posto; il trattamento degli eccezioni del codice è completo e ragionevole, l'indentazione del codice è elegante e generosa, i nomi delle variabili sono intuitivi e facili da capire; combinato con commenti di lunghezza moderata e chiari, il programma offre un senso di freschezza e originalità. Dietro di questo si vede l'amore dell'autore per lo studio e la severità nel design, lo spirito artigianale è evidente, e può veramente essere considerato un esempio di applicazione pratica della struttura dei dati universitari!

 

Ecco l'implementazione del codice:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.TextField;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Stack;
import javax.swing.JFrame;
/** * Programma calcolatrice con interfaccia grafica, può calcolare addizione, sottrazione, moltiplicazione e divisione, * Le espressioni possono contenere parentesi tonde. I numeri possono essere decimali */
public class CalcGUI extends JFrame{
  private static final long serialVersionUID = 1L;
  private TreeNode resultTree;
  private String textFieldString;
  private boolean calcSuccess = true;
  private char ops[][] = {
      {'>', '>', '<', '<', '<', '>', '>'},
      {'>', '>', '<', '<', '<', '>', '>'},
      {'>', '>', '>', '>', '<', '>', '>'},
      {'>', '>', '>', '>', '<', '>', '>'},
      {'<', '<', '<', '<', '<', '=', 'E'},
      {'E', 'E', 'E', 'E', 'E', 'E', 'E'},
      {'<', '<', '<', '<', '<', 'E', '='},
  };
  Stack<TreeNode> nodesStack = new Stack<TreeNode>();
  Stack<Character> opsStack = new Stack<Character>();
  public static void main(String[] args) {
    CalcGUI gui = new CalcGUI();
    gui.userGUI();
  }
  public void userGUI(){
    this.setLayout(new BorderLayout());
    TextField tf = new TextField("Inserisci l'espressione, premi Enter per iniziare il calcolo~", 40);
    tf.selectAll();
    tf.getText();
    tf.addKeyListener(new KeyAdapter(){
      public void keyPressed(KeyEvent e){
        if(e.getKeyCode() == KeyEvent.VK_ENTER){
          textFieldString = ((TextField)e.getComponent()).getText();
          calcSuccess = true;
          resultTree = null;
          try{
            resultTree = calc(textFieldString + "#");
          } catch(Exception e1) {}}
            calcSuccess = false;
          }
          CalcGUI.this.repaint();
        }
      }
    });
    this.add(tf, BorderLayout.NORTH);
    this.setSize(500, 500);
    this.setTitle("calc GUI");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setResizable(true);
    this.setVisible(true);
  }
  private int levelHeight = 60;
  private int diameter = 25;
  public void paint(Graphics g) {
    super.paint(g);
    if(calcSuccess) {
      if(resultTree != null) {
        g.drawString("Il risultato del calcolo è: " + resultTree.value, 10, 80);
        int rootBeginX = this.getWidth() / 2;
        int rootBeginY = 100;
        Point p = new Point(rootBeginX, rootBeginY);
        drawTree(g, resultTree, p, this.getWidth() / 2 - 20, p);
      }
    }else{
      g.setColor(Color.RED);
      g.drawString("Espressione grammaticale errata!", 10, 80);
    }
  }
  private void drawCircle(Graphics g, Point p, int r) {
    g.drawOval(p.x - r, p.y - r, r * 2, r * 2);
  }
  private void drawTree(Graphics g, TreeNode node, Point pme, int width, Point pfather) {
    if(node == null) return;
//   System.out.println("in drawTree, node.value=" + node.value + ",node.op=" + node.op);
    g.setColor(Color.GREEN);
    this.disegnaCerchio(g, pme, diameter / 2);
    g.drawLine(pme.x, pme.y, pfather.x, pfather.y);
    if(node.op != 'E'){
      g.setColor(Color.BLACK);
      g.drawString(String.valueOf(node.op), pme.x, pme.y);
    }else{
      g.setColor(Color.BLACK);
      g.drawString(String.valueOf(node.value), pme.x - diameter / 2, pme.y);
    }
    disegnaAlbero(g, node.lft, new Point(pme.x - width / 2, pme.y + levelHeight), width / 2, pme);
    disegnaAlbero(g, node.rt, new Point(pme.x + width / 2, pme.y + levelHeight), width / 2, pme);
  }
  public TreeNode calc(String inStr) throws Exception{
    opsStack.push('#');
    StringBuilder buf = new StringBuilder();
    int i = 0;
    while(i < inStr.length()){
      if(Character.isDigit(inStr.charAt(i)) || inStr.charAt(i) == '.'){// numero
        buf.delete(0, buf.length());
        while(i < inStr.length() && 
            (Character.isDigit(inStr.charAt(i)) || inStr.charAt(i) == '.')
          buf.append(inStr.charAt(i++));
        Double number = Double.parseDouble(buf.toString());
        nodesStack.push(new TreeNode(number));
      }
        i++;
        continua;
      else{// operazione
        char op = inStr.charAt(i);
        int subNew = getSub(op);
        boolean goOn = true;
        while(goOn){
          if(opsStack.isEmpty())
            throw new Exception("运算符数量不足!");
          char opFormer = opsStack.peek();
          int subFormer = getSub(opFormer);
          switch(ops[subFormer][subNew]){
          case '=':
            goOn = false;
            opsStack.pop();
            break;
          case '<':
            goOn = false;
            opsStack.push(op);
            break;
          case '>':
            goOn = true;
            TreeNode n1 = nodesStack.pop();
            TreeNode n0 = nodesStack.pop();
            double rs = doOperate(n0.value, n1.value, opFormer);
            nodesStack.push(new TreeNode(rs, opFormer, n0, n1));
            opsStack.pop();
            break;
          default:
            throw new Exception("没有匹配的操作符:" + op);
          }
        }
        i++;
      }
    }
    return nodesStack.pop();
  }
  private double doOperate(double n0, double n1, char op) throws Exception{
    switch(op){
    case '+': return n0 + n1;
    case '-': return n0 - n1;
    case '*': return n0 * n1;
    case '/': return n0 / n1;
    default: throw new Exception("操作符非法:" + op);
    }
  }
  private int getSub(char c){
    switch(c){
      case '+': return 0;
      case '-': return 1;
      case '*': return 2;
      case '/': return 3;
      case '(': return 4;
      case ')': return 5;
      case '#': return 6;
      default : return -1;
    }
  }
}
class TreeNode{
  public double value;
  public char op = 'E';
  public TreeNode lft;
  public TreeNode rt;
  public TreeNode(double value){
    this.value = value;
  }
  public TreeNode(double value, char op, TreeNode lft, TreeNode rt){
    this.value = value;
    this.op = op;
    this.lft = lft;
    this.rt = rt;
  }
  StringBuilder buf = new StringBuilder();
  public String toString(){
    out(this);
    return buf.toString();
  }
  private void out(TreeNode node){
    if(node == null) return;
    out(node.lft);
    if(node.op != 'E')
      buf.append(node.op);
    else
      buf.append(node.value);
    out(node.rt);
  }
}

Conclusione

Come già descritto dall'autore, 200 righe di codice Java per creare un programma calcolatrice, spero sia utile a tutti. Se avete qualsiasi domanda, lasciate un commento e l'autore risponderà prontamente. In questo senso, l'autore desidera ringraziare tutti i sostenitori della guida a urla!

Ti potrebbe interessare