<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
本文範例為大家分享了Java實現簡易計算器的具體程式碼,供大家參考,具體內容如下
程式的執行環境為Windows10 ,編譯環境為IDEA。
計算器有以下功能和要求:能夠計算複雜表示式,實現對多位數和負數以及小數的多則複雜計算
1,能夠計算大數位,小數,負數
2,小數點,運運算元等不能連續輸入(例如 ..,++,**等)
3,小數點前沒有數位時自動補0並在輸入框顯示“0.”若小數點前是數位,且前面的數位串裡含有".",則不能繼續輸入小數點(“.”---”0.“ ,1.11後面不能繼續輸入小數點)
4,‘(’左邊和‘)’右邊輸入數位時,有運運算元不做操作,無運運算元自動補"*",")"後跟"(',在中間加‘*’(例如“7(”--“7*(”,“)7”--“(*7)”,“(1+1)(2+2)”--“(1+1)*(2+2)”)
5,輸入的")"不能多於"(",且相鄰()之間不能為空(“()”--X,“((1+2)))--X)
6,能計算負數,符號前面沒有數位則補0 (-6-1 -- 0-6-1)
7,運運算元除"-"號外不能第一個輸入,若不是第一次計算,則可以直接輸入,將上一個表示式的結果作為此次表示式的第一個運算數
8,檢視歷史記錄,清空當前記錄,清空歷史記錄,退格操作
執行結果如圖:
1. 初始化介面
通過 this 方法設定包括介面的大小,介面的位置(可根據螢幕設定中間位置),按鍵北面和中間排版及其顏色和大小,採用GridLayout網格佈局
通過迴圈設定按鍵的位置,並將運運算元加粗,並將所有按鍵和排版串聯到介面上
class Main { public static class Calculator extends JFrame implements ActionListener { // 初始化介面 public void init() { this.setTitle("計算器"); history.setEditable(false); history.setFont(new Font("宋體", Font.PLAIN, 30)); this.setSize(477, 577); //介面大小 this.setLayout(new BorderLayout()); this.setResizable(false); this.setLocationRelativeTo(null); //介面位置設定居中 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } //北面的控制元件 private final JPanel key_north = new JPanel(); private final JTextField input_text = new JTextField(); private final JTextArea history = new JTextArea(); private final JButton c_btn = new JButton("C"); private final JButton ALLc_btn = new JButton("AC"); //中間的控制元件 private final JPanel center = new JPanel(); //將介面串聯 public Calculator() throws HeadlessException { this.init(); this.addNorthCompent(); this.addCenterButton(); } //新增北面控鍵 public void addNorthCompent() { this.history.setPreferredSize(new Dimension(350, 200)); this.input_text.setPreferredSize(new Dimension(450, 30));//輸入框的大小 input_text.setBackground(new Color(127,255,212)); this.key_north.setBackground(new Color(193,255,193)); this.history.setBackground(new Color(193,255,120)); key_north.add(input_text); key_north.add(history); this.c_btn.setForeground(new Color(0,139,139));//按鍵顏色 this.ALLc_btn.setBackground(new Color(0,205,205)); key_north.add(c_btn); key_north.add(ALLc_btn); c_btn.setBackground(Color.CYAN); c_btn.addActionListener(new ActionListener() { //為清除操作設定監聽 @Override public void actionPerformed(ActionEvent e) { firstint = ""; input_text.setText(""); } }); ALLc_btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { input_text.setText(""); firstint = ""; hitory = ""; history.setText(""); } }); this.add(key_north, BorderLayout.NORTH); } //新增中間按鍵 public void addCenterButton() { String key_text = "H()←123+456-789*0.=/";//中間控制元件排版 this.center.setLayout(new GridLayout(5, 4)); String regex = "[+\-*/=H()←]"; for (int i = 0; i < 20; i++) { //初始化按鍵 String temp = key_text.substring(i, i + 1); JButton key = new JButton(); key.setFont(new Font("宋體",Font.BOLD,20)); key.setForeground(new Color(69,139,116)); key.setBackground(new Color(193,255,193)); key.setText(temp); if (temp.matches(regex)) { //將運運算元加粗並更改顏色 key.setFont(new Font("粗體", Font.BOLD, 30)); key.setForeground(new Color(102,205,170)); } key.addActionListener(this); center.add(key); } this.add(center, BorderLayout.CENTER); }
2. 計算器功能設計
設定監聽
設兩個空字串,一個用來儲存表示式,另一個用來儲存歷史記錄
為所有按鍵設定監聽功能,將輸入的表示式顯示到文字方塊的右邊,並實現計算結果,檢視歷史記錄,清空歷史記錄,計算器表示式退格功能,判斷表示式合法性.
@Override public void actionPerformed(ActionEvent e) { //監聽功能 String strings = e.getActionCommand();//儲存記錄 //JOptionPane.showMessageDialog(this,strings);//監聽 if ("0123456789".contains(strings)) { if (Objects.equals(firstint, "")) { //輸入新的表示式,清除掉上一個表示式結果 firstint+=strings; this.input_text.setText(strings); this.input_text.setHorizontalAlignment(JTextField.RIGHT);//顯示到右邊 }else if(strings.equals("0")){ if (Objects.equals(firstint, "0")) { this.input_text.setText(firstint); }else { int index = 0; for ( int i=firstint.length()-1;i >=0;i-- ) { if(isSymbol(firstint.substring(index))){ index=i; } } if (!firstint.substring(index+1, firstint.length() - 1).equals("0")) { firstint += strings; } this.input_text.setText(firstint); } } else if(firstint.charAt(firstint.length()-1)==')'){ //)後輸入數位補*號 firstint+="*"+strings; this.input_text.setText(firstint); }else {this.input_text.setText(input_text.getText() + strings);//將輸入的數記錄並將之前的數放到前面 this.input_text.setHorizontalAlignment(JTextField.RIGHT);//顯示到右邊 firstint += strings; System.out.println(firstint);} } else if (strings.equals(".")) { if (Objects.equals(firstint, "")) { if (!Objects.equals(ans, "")) { firstint = ans + "."; this.input_text.setText(firstint); }else {this.input_text.setText(input_text.getText() + "0" + strings); this.input_text.setHorizontalAlignment(JTextField.RIGHT); //自帶補0 firstint = "0" + strings;} } else if(firstint.charAt(firstint.length() - 1) == ')'){ //)後輸入小數點補0 firstint =firstint+ "*0"+strings; this.input_text.setText(firstint); } else if (firstint.charAt(firstint.length() - 1) == '.') { //不能連續小數點 this.input_text.setText(firstint); this.input_text.setHorizontalAlignment(JTextField.RIGHT); } else if (!ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length() - 1))) && !String.valueOf(firstint.charAt(firstint.length() - 1)).equals(".")) { this.input_text.setText(input_text.getText() + "0" + strings); //前一個既不是數位也不是小數補0 this.input_text.setHorizontalAlignment(JTextField.RIGHT); firstint = firstint + "0" + strings; } else if (ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length() - 1)))) {//如果前面是數位之間輸入 int count = 0, i = 0; for (i = firstint.length() - 1; i > 0; i--) { //查詢前面的數位串中有沒有小數點 if (ToPolland.isSymbol(String.valueOf(firstint.charAt(i)))) { break; }//直到遇到下一個運運算元時結束查詢 else if (firstint.charAt(i) == '.') { count++; } } if (count == 0) { //判斷前面的數位串沒有小數點 this.input_text.setText(input_text.getText() + strings); this.input_text.setHorizontalAlignment(JTextField.RIGHT); firstint = firstint + strings; } } } else if (strings.matches("[+\-*/]")) { if (Objects.equals(firstint, "")) { //運運算元前必須有運算數 if (!Objects.equals(ans, "")) { firstint += ans+strings; this.input_text.setText(firstint); } if(strings.equals("-")){ //減號第一個輸入當做負號 this.input_text.setHorizontalAlignment(JTextField.RIGHT); this.input_text.setText("-"); firstint += strings; } //JOptionPane.showMessageDialog(null, "請先輸入運算元"); }else if(firstint.charAt(firstint.length()-1)=='.'){ //小數點後不能跟運運算元 this.input_text.setText(firstint); } else if (firstint.charAt(firstint.length() - 1)=='('){ //(後只能跟-號運運算元 if(strings.equals("-")){ firstint+=strings; this.input_text.setText(firstint); } } else if (ToPolland.isSymbol(String.valueOf(firstint.charAt(firstint.length() - 1)))&&strings!="-") { this.input_text.setText(firstint); } else { this.input_text.setText(input_text.getText() + strings); firstint = firstint + strings; System.out.println(firstint); } } else if (strings.matches("[()]{1}")) { if (strings.equals("(")) { if(Objects.equals(firstint, "") ||firstint.charAt(firstint.length()-1)=='('){ firstint+="("; this.input_text.setText(firstint); this.input_text.setHorizontalAlignment(JTextField.RIGHT); }else if(firstint.charAt(firstint.length() - 1) == ')'){ firstint+="*"+strings; this.input_text.setText(firstint); } else if(ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length()-1)))){ firstint+="*"+strings; this.input_text.setText(firstint); }else if(ToPolland.isSymbol(String.valueOf(firstint.charAt(firstint.length()-1)))){ firstint+=strings;this.input_text.setText(firstint); } System.out.println(firstint); } else if (strings.equals(")") && firstint != "") { if(ToPolland.isSymbol(String.valueOf(firstint.charAt(firstint.length()-1)))){ this.input_text.setText(firstint); }else if (firstint.charAt(firstint.length() - 1) != '(') { int count1 = 0, count2 = 1; for (int i = 0; i < firstint.length(); i++) { //找出()的個數 if (firstint.charAt(i) == '(') { count1++; } if (firstint.charAt(i) == ')') { count2++; } } if (count1 >= count2) { (個數必須大於等於)個數 this.input_text.setText(input_text.getText() + strings); firstint = firstint + strings; System.out.println(firstint); } } } } else if (strings.equals("=")) { //計算結果 try { if(firstint.charAt(firstint.length()-1)=='.'){ firstint=firstint.substring(0,firstint.length()-2); }System.out.println(firstint); StringBuilder builder = new StringBuilder(); List<String> list = toPolland(ToPolland.toList(firstint)); list.forEach(builder::append); System.out.println("算式表示式:" + firstint); System.out.println("轉逆波蘭表示式:" + builder); System.out.println("轉逆波蘭表示式計算結果:" + firstint + "=" + ToPolland.calculate(list)); ans = String.valueOf(ToPolland.calculate(list)); this.input_text.setText("" + ToPolland.calculate(list)); hitory += firstint + "=" + ToPolland.calculate(list) + "n"; firstint = ""; } catch (Exception e1) { JOptionPane.showMessageDialog(null, "表示式錯誤"); firstint = ""; this.input_text.setText(""); } } else if (strings.equals("H")) { //檢視歷史記錄 history.setFont(new Font("宋體", Font.BOLD, 20)); this.history.setText(hitory); } else if (strings.equals("C")) { //清空當前記錄 firstint = ""; this.input_text.setText(""); } else if (strings.equals("AC")) { //清空歷史記錄 firstint = ""; hitory = ""; this.history.setText(""); this.input_text.setText(""); } else if (strings.equals("←") && firstint.length() != 0) { //退格 firstint = firstint.substring(0, firstint.length() - 1); System.out.println(firstint); this.input_text.setText("" + firstint.substring(0, firstint.length())); } } }
1、將中綴表示式轉為 list 結構
中綴轉字尾表示式時需要先將中綴表示式轉為 list 結構,在這個過程中,可以分析表示式的合理性,將表示式進行處理(去掉空格及其他錯誤的符號),判斷表示式的正確性並給予反饋 . 我們處理的時候還需要注意多位數位的處理,可以利用一個字元陣列對多位數位和小數進行拼接
//將表示式存入list public static List<String> toList(String strings) { strings = tList(strings); if (strings == null || strings.length() <= 0) { throw new NullPointerException("表示式不能為空!"); } // 去掉不合法的符號 strings = strings.replaceAll("\s*|t|r|n", ""); List<String> list = new ArrayList<>(); char[] chars = strings.toCharArray(); String ch="",str=""; for (int i = 0; i < chars.length; i++) { // 判斷是否是數位 if (!Character.isDigit((chars[i]))) { list.add(String.valueOf(chars[i])); } else { //如果是數位,就判斷下一個是不是數位,如果是就進行組合(迴圈),然後錄入list do { ch = String.valueOf(chars[i]); //讀取一個字元 str += ch; //進行拼接 i++; //不是最後一個字元,並且下一個還是數位或者小數點,就進行迴圈 } while ((i < strings.length()) && ((chars[i] <= 57 && chars[i] >= 48) || '.' == chars[i])); list.add(str);//將拼接的字串錄入到list str = "";i--; System.out.println(list);//這裡一定要將str置位初值 } } return list; }
需要注意的是當輸入的表示式中存在負數時,需要在負號前面補0,或者將負號後面的表示式中的一個計算符取反,否則轉為逆波蘭表示式後得不到正確的結果。
//表示式中存在負數時,後面的逆波蘭表示式演演算法無法得到正確結果,需要補0 public static String tList(String strings) { String stringBuilder = ""; if(strings.charAt(0)=='-'){//如果第一個字元是‘-',在負號前面補0 stringBuilder+= "0"; } stringBuilder+=strings.charAt(0); //將第一個‘-'號接到0後面 //如果遇到負號,並且負號前面的符號不是數位,在負號前面補0 for (int i = 1; i < strings.length(); i++) { if (strings.charAt(i) == '-' && (isNumber(String.valueOf(strings.charAt(i - 1))) == false)) { stringBuilder += "0" + strings.charAt(i); } else stringBuilder += strings.charAt(i);//沒有負號則直接拼接 } return stringBuilder; }
2、逆波蘭表示式的轉化(單棧法)
採用單棧來和一個佇列對錶示式進行操作,也可以採用雙棧法處理表示式
構造判斷數位,計算符以及優先順序的方法
實現程式碼如下:
//轉逆波蘭表示式 public static List<String> toPolland(List<String> list) { Stack<String> s1 = new Stack(); List<String> s2 = new ArrayList<>(); // 從左至右掃描中綴表示式; for (String item : list) { // 遇到運算元時,將其壓s2; if (Pattern.matches("-?[0-9]+(\.[0-9]+)?", item)) { s2.add(item); }//遇到操作符時,比較其與棧頂的操作符的優先順序 if (isSymbol(item)) { while (s1.size() > 0 && isSymbol(s1.peek()) && priority(item) <= priority(s1.peek())) { s2.add(s1.pop()); } s1.push(item); } if (item.equals("(")) { //右括號直接入棧 s1.push(item); } if (item.equals(")")) { //遇到右括號,將左括號之前的操作符全部出棧 while (!s1.peek().equals("(")) { s2.add(s1.pop()); } // 將左邊的括號,彈棧 s1.pop(); } } while (s1.size() > 0) { //將剩餘的操作符全部入棧 s2.add(s1.pop()); } return s2; }
判斷數位和運運算元已經比較運運算元優先順序:
//判斷是否為數位 public static boolean isNumber(String str) { return Pattern.matches("-?[0-9]+(\.[0-9]+)?", str); } //是否是運運算元 public static boolean isSymbol(String str) { return "+-*/".contains(str); } //返回運運算元的優先順序 public static int priority(String value) { if ("+-".contains(value)) { return 1; } else if ("*/".contains(value)) { return 2; } else { throw new RuntimeException("暫不支援操作符:" + value); } }
3、逆波蘭表示式(字尾表示式)的計算
首先準備一個棧Res_Stack.
1、從左開始向右遍歷字尾表示式的元素。
2、如果取到的元素是運算元,直接入棧Res_Stack,如果是運運算元,從棧中彈出2個數進行運算,然後把運算結果入棧
3、當遍歷完字尾表示式時,計算結果就儲存在棧裡了。
演演算法思想:
程式碼如下:
//逆波蘭表示式的計算 public static BigDecimal calculate(List<String> nipollands) { if (nipollands == null || nipollands.size() <= 1) { throw new NullPointerException("逆波蘭表示式列表不能為空!"); } Stack<BigDecimal> stack = new Stack(); for (String nipolland : nipollands) { if (isNumber(nipolland)) { //數位直接入棧 stack.push(new BigDecimal(nipolland)); } else { //遇到操作符取出兩個數進行對應的計算,並將計算結果入棧 BigDecimal number1 = stack.pop(); BigDecimal number2 = stack.pop(); BigDecimal result; switch (nipolland) { case "+" -> result=number2.add(number1); case "-" -> result=number2.subtract(number1); case "*" -> result=number2.multiply(number1); case "/" -> result=number2.divide(number1, 3,RoundingMode.HALF_UP); default -> throw new RuntimeException("不合法操作符:" + nipolland); } stack.push(result);//遍歷字串後得到的棧頂既為逆波蘭表示式計算結果 } } return stack.pop(); }
完整程式碼:
package com.company; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Stack; import java.util.regex.Pattern; import static com.company.ToPolland.toPolland; class Main { public static class Calculator extends JFrame implements ActionListener { // 初始化介面 public void init() { this.setTitle("計算器"); history.setEditable(false); history.setFont(new Font("宋體", Font.PLAIN, 30)); this.setSize(477, 577); //介面大小 this.setLayout(new BorderLayout()); this.setResizable(false); this.setLocationRelativeTo(null); //介面位置設定居中 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } //北面的控制元件 private final JPanel key_north = new JPanel(); private final JTextField input_text = new JTextField(); private final JTextArea history = new JTextArea(); private final JButton c_btn = new JButton("C"); private final JButton ALLc_btn = new JButton("AC"); //中間的控制元件 private final JPanel center = new JPanel(); //將介面串聯 public Calculator() throws HeadlessException { this.init(); this.addNorthCompent(); this.addCenterButton(); } //新增北面控鍵 public void addNorthCompent() { this.history.setPreferredSize(new Dimension(350, 200)); this.input_text.setPreferredSize(new Dimension(450, 30));//輸入框的大小 input_text.setBackground(new Color(127,255,212)); this.key_north.setBackground(new Color(193,255,193)); this.history.setBackground(new Color(193,255,120)); key_north.add(input_text); key_north.add(history); this.c_btn.setForeground(new Color(0,139,139));//按鍵顏色 this.ALLc_btn.setBackground(new Color(0,205,205)); key_north.add(c_btn); key_north.add(ALLc_btn); c_btn.setBackground(Color.CYAN); c_btn.addActionListener(new ActionListener() { //為清除操作設定監聽 @Override public void actionPerformed(ActionEvent e) { firstint = ""; input_text.setText(""); } }); ALLc_btn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { input_text.setText(""); firstint = ""; hitory = ""; history.setText(""); } }); this.add(key_north, BorderLayout.NORTH); } //新增中間按鍵 public void addCenterButton() { String key_text = "H()←123+456-789*0.=/";//中間控制元件排版 this.center.setLayout(new GridLayout(5, 4)); String regex = "[+\-*/=H()←]"; for (int i = 0; i < 20; i++) { //初始化按鍵 String temp = key_text.substring(i, i + 1); JButton key = new JButton(); key.setFont(new Font("宋體",Font.BOLD,20)); key.setForeground(new Color(69,139,116)); key.setBackground(new Color(193,255,193)); key.setText(temp); if (temp.matches(regex)) { //將運運算元加粗並更改顏色 key.setFont(new Font("粗體", Font.BOLD, 30)); key.setForeground(new Color(102,205,170)); } key.addActionListener(this); center.add(key); } this.add(center, BorderLayout.CENTER); } private String firstint = "";//儲存表示式 static String hitory = "";//儲存歷史記錄 static String ans = ""; @Override public void actionPerformed(ActionEvent e) { //監聽功能 String strings = e.getActionCommand();//儲存記錄 //JOptionPane.showMessageDialog(this,strings);//監聽 if ("0123456789".contains(strings)) { if (firstint == "") { firstint+=strings; this.input_text.setText(strings); this.input_text.setHorizontalAlignment(JTextField.RIGHT);//顯示到右邊 }else if(firstint.charAt(firstint.length()-1)==')'){ firstint+="*"+strings; this.input_text.setText(firstint); }else {this.input_text.setText(input_text.getText() + strings);//將輸入的數記錄並將之前的數放到前面 this.input_text.setHorizontalAlignment(JTextField.RIGHT);//顯示到右邊 firstint += strings; System.out.println(firstint);} } else if (strings.equals(".")) { if (firstint == "") { this.input_text.setText(input_text.getText() + "0" + strings); this.input_text.setHorizontalAlignment(JTextField.RIGHT); firstint = "0" + strings; } else if(firstint.charAt(firstint.length() - 1) == ')'){ firstint =firstint+ "*0"+strings; this.input_text.setText(firstint); } else if (firstint.charAt(firstint.length() - 1) == '.') { //不能連續小數點 this.input_text.setText(firstint); this.input_text.setHorizontalAlignment(JTextField.RIGHT); } else if (!ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length() - 1))) && String.valueOf(firstint.charAt(firstint.length() - 1)) != ".") { this.input_text.setText(input_text.getText() + "0" + strings); //前一個既不是數位也不是小數補0 this.input_text.setHorizontalAlignment(JTextField.RIGHT); firstint = firstint + "0" + strings; } else if (ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length() - 1)))) {//如果前面是數位之間輸入 int count = 0, i = 0; for (i = firstint.length() - 1; i > 0; i--) { //查詢前面的數位串中有沒有小數點 if (ToPolland.isSymbol(String.valueOf(firstint.charAt(i)))) { break; }//直到遇到下一個運運算元時結束查詢 else if (firstint.charAt(i) == '.') { count++; } } if (count == 0) { //判斷前面的數位串沒有小數點 this.input_text.setText(input_text.getText() + strings); this.input_text.setHorizontalAlignment(JTextField.RIGHT); firstint = firstint + strings; } } } else if (strings.matches("[+\-*/]{1}")) { if (firstint == "") { if (ans != "") { firstint += ans+strings; this.input_text.setText(firstint); } if(strings=="-"){ firstint += strings; this.input_text.setText(input_text.getText()+strings); } //JOptionPane.showMessageDialog(null, "請先輸入運算元"); } else if (ToPolland.isSymbol(String.valueOf(firstint.charAt(firstint.length() - 1)))&&strings!="-") { JOptionPane.showMessageDialog(null, "表示式錯誤"); } else { this.input_text.setText(input_text.getText() + strings); firstint = firstint + strings; System.out.println(firstint); } } else if (strings.matches("[()]{1}")) { if (strings.equals("(")) { if(firstint==""){ firstint+="("; this.input_text.setText(firstint); this.input_text.setHorizontalAlignment(JTextField.RIGHT); }else if(ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length()-1)))){ firstint+="*"+strings; this.input_text.setText(firstint); }else if(ToPolland.isSymbol(String.valueOf(firstint.charAt(firstint.length()-1)))){ firstint+=strings;this.input_text.setText(firstint); } System.out.println(firstint); } else if (strings.equals(")") && firstint != "") { if (firstint.charAt(firstint.length() - 1) != '(') { int count1 = 0, count2 = 1; for (int i = 0; i < firstint.length(); i++) { if (firstint.charAt(i) == '(') { count1++; } if (firstint.charAt(i) == ')') { count2++; } } if (count1 >= count2) { this.input_text.setText(input_text.getText() + strings); firstint = firstint + strings; System.out.println(firstint); } } } } else if (strings.equals("=")) { //計算結果 try { System.out.println(firstint); StringBuilder builder = new StringBuilder(); List<String> list = toPolland(ToPolland.toList(firstint)); list.forEach(builder::append); System.out.println("算式表示式:" + firstint); System.out.println("轉逆波蘭表示式:" + builder); System.out.println("轉逆波蘭表示式計算結果:" + firstint + "=" + ToPolland.calculate(list)); ans = String.valueOf(ToPolland.calculate(list)); this.input_text.setText("" + ToPolland.calculate(list)); hitory += firstint + "=" + ToPolland.calculate(list) + "n"; firstint = ""; } catch (Exception e1) { JOptionPane.showMessageDialog(null, "表示式錯誤"); firstint = ""; this.input_text.setText(""); } } else if (strings.equals("H")) { //檢視歷史記錄 history.setFont(new Font("宋體", Font.BOLD, 20)); this.history.setText(hitory); } else if (strings.equals("C")) { //清空當前記錄 firstint = ""; this.input_text.setText(""); } else if (strings.equals("AC")) { //清空歷史記錄 firstint = ""; hitory = ""; this.history.setText(""); this.input_text.setText(""); } else if (strings.equals("←") && firstint.length() != 0) { //退格 firstint = firstint.substring(0, firstint.length() - 1); System.out.println(firstint); this.input_text.setText("" + firstint.substring(0, firstint.length())); } } } public static void main(String[] args) { Calculator carculator = new Calculator(); carculator.setVisible(true); } public class ToPolland { //表示式中存在負數時,後面的逆波蘭表示式演演算法無法得到正確結果,需要補0 public static String tList(String strings) { String stringBuilder = ""; if(strings.charAt(0)=='-'){//如果第一個字元是‘-',在負號前面補0 stringBuilder+= "0"; } stringBuilder+=strings.charAt(0); //將第一個‘-'號接到0後面 //如果遇到負號,並且負號前面的符號不是數位,在負號前面補0 for (int i = 1; i < strings.length(); i++) { if (strings.charAt(i) == '-' && (!isNumber(String.valueOf(strings.charAt(i - 1))))) { stringBuilder += "0" + strings.charAt(i); } else stringBuilder += strings.charAt(i);//沒有負號則直接拼接 } return stringBuilder; } //將表示式存入list public static List<String> toList(String strings) { strings = tList(strings); if (strings == null || strings.length() <= 0) { throw new NullPointerException("表示式不能為空!"); } // 去掉不合法的符號 strings = strings.replaceAll("\s*|t|r|n", ""); List<String> list = new ArrayList<>(); char[] chars = strings.toCharArray(); String ch="",str=""; for (int i = 0; i < chars.length; i++) { // 判斷是否是數位 if (!Character.isDigit((chars[i]))) { list.add(String.valueOf(chars[i])); } else { //如果是數位,就判斷下一個是不是數位,如果是就進行組合(迴圈),然後錄入list do { ch = String.valueOf(chars[i]); //讀取一個字元 str += ch; //進行拼接 i++; //不是最後一個字元,並且下一個還是數位或者小數點,就進行迴圈 } while ((i < strings.length()) && ((chars[i] <= 57 && chars[i] >= 48) || '.' == chars[i])); list.add(str);//將拼接的字串錄入到list str = "";i--; System.out.println(list);//這裡一定要將str置位初值 } } return list; } //轉逆波蘭表示式 public static List<String> toPolland(List<String> list) { Stack<String> s1 = new Stack(); List<String> s2 = new ArrayList<>(); // 從左至右掃描中綴表示式; for (String item : list) { // 遇到運算元時,將其壓s2; if (Pattern.matches("-?[0-9]+(\.[0-9]+)?", item)) { s2.add(item); }//遇到操作符時,比較其與棧頂的操作符的優先順序 if (isSymbol(item)) { while (s1.size() > 0 && isSymbol(s1.peek()) && priority(item) <= priority(s1.peek())) { s2.add(s1.pop()); } s1.push(item); } if (item.equals("(")) { //右括號直接入棧 s1.push(item); } if (item.equals(")")) { //遇到右括號,將左括號之前的操作符全部出棧 while (!s1.peek().equals("(")) { s2.add(s1.pop()); } s1.pop();// 將左邊的括號,彈棧 } } while (s1.size() > 0) { //將剩餘的操作符全部入棧 s2.add(s1.pop()); } return s2; } //逆波蘭表示式的計算 public static BigDecimal calculate(List<String> nipollands) { if (nipollands == null || nipollands.size() <= 1) { throw new NullPointerException("逆波蘭表示式列表不能為空!"); } Stack<BigDecimal> stack = new Stack(); for (String nipolland : nipollands) { if (isNumber(nipolland)) { //數位直接入棧 stack.push(new BigDecimal(nipolland)); } else { //遇到操作符取出兩個數進行對應的計算,並將計算結果入棧 BigDecimal number1 = stack.pop(); BigDecimal number2 = stack.pop(); BigDecimal result; switch (nipolland) { case "+" -> result=number2.add(number1); case "-" -> result=number2.subtract(number1); case "*" -> result=number2.multiply(number1); case "/" -> result=number2.divide(number1, 3,RoundingMode.HALF_UP); default -> throw new RuntimeException("不合法操作符:" + nipolland); } stack.push(result);//遍歷字串後得到的棧頂既為逆波蘭表示式計算結果 } } return stack.pop(); } //判斷是否為數位 public static boolean isNumber(String str) { return Pattern.matches("-?[0-9]+(\.[0-9]+)?", str); } //是否是運運算元 public static boolean isSymbol(String str) { return "+-*/".contains(str); } //返回運運算元的優先順序 public static int priority(String value) { if ("+-".contains(value)) { return 1; } else if ("*/".contains(value)) { return 2; } else { throw new RuntimeException("暫不支援操作符:" + value); } } }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援it145.com。
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45