Java實(shí)現(xiàn)簡易計(jì)算器(逆波蘭表達(dá)式)
本文實(shí)例為大家分享了Java實(shí)現(xiàn)簡易計(jì)算器的具體代碼,供大家參考,具體內(nèi)容如下
程序的運(yùn)行環(huán)境為Windows10 ,編譯環(huán)境為IDEA。
計(jì)算器有以下功能和要求:能夠計(jì)算復(fù)雜表達(dá)式,實(shí)現(xiàn)對(duì)多位數(shù)和負(fù)數(shù)以及小數(shù)的多則復(fù)雜計(jì)算
已完善功能(Bug):
1,能夠計(jì)算大數(shù)字,小數(shù),負(fù)數(shù)
2,小數(shù)點(diǎn),運(yùn)算符等不能連續(xù)輸入(例如 ..,++,**等)
3,小數(shù)點(diǎn)前沒有數(shù)字時(shí)自動(dòng)補(bǔ)0并在輸入框顯示“0.”若小數(shù)點(diǎn)前是數(shù)字,且前面的數(shù)字串里含有".",則不能繼續(xù)輸入小數(shù)點(diǎn)(“.”---”0.“ ,1.11后面不能繼續(xù)輸入小數(shù)點(diǎn))
4,‘(’左邊和‘)’右邊輸入數(shù)字時(shí),有運(yùn)算符不做操作,無運(yùn)算符自動(dòng)補(bǔ)"*",")"后跟"(',在中間加‘*’(例如“7(”--“7*(”,“)7”--“(*7)”,“(1+1)(2+2)”--“(1+1)*(2+2)”)
5,輸入的")"不能多于"(",且相鄰()之間不能為空(“()”--X,“((1+2)))--X)
6,能計(jì)算負(fù)數(shù),符號(hào)前面沒有數(shù)字則補(bǔ)0 (-6-1 -- 0-6-1)
7,運(yùn)算符除"-"號(hào)外不能第一個(gè)輸入,若不是第一次計(jì)算,則可以直接輸入,將上一個(gè)表達(dá)式的結(jié)果作為此次表達(dá)式的第一個(gè)運(yùn)算數(shù)
8,查看歷史記錄,清空當(dāng)前記錄,清空歷史記錄,退格操作
運(yùn)行結(jié)果如圖:
實(shí)現(xiàn)過程:
一、計(jì)算器界面設(shè)計(jì)
1. 初始化界面
通過 this 方法設(shè)置包括界面的大小,界面的位置(可根據(jù)屏幕設(shè)置中間位置),按鍵北面和中間排版及其顏色和大小,采用GridLayout網(wǎng)格布局
通過循環(huán)設(shè)置按鍵的位置,并將運(yùn)算符加粗,并將所有按鍵和排版串聯(lián)到界面上
class Main { ? ? public static class Calculator extends JFrame implements ActionListener { ? ? ? ? // ?初始化界面 ? ? ? ? public void init() { ? ? ? ? ? ? this.setTitle("計(jì)算器"); ? ? ? ? ? ? history.setEditable(false); ? ? ? ? ? ? history.setFont(new Font("宋體", Font.PLAIN, 30)); ? ? ? ? ? ? this.setSize(477, 577); //界面大小 ? ? ? ? ? ? this.setLayout(new BorderLayout()); ? ? ? ? ? ? this.setResizable(false); ? ? ? ? ? ? this.setLocationRelativeTo(null); ? //界面位置設(shè)置居中 ? ? ? ? ? ? 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(); ? ? ? ? ? //將界面串聯(lián) ? ? ? ? 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() { ?//為清除操作設(shè)置監(jiān)聽 ? ? ? ? ? ? ? ? @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)) { ? //將運(yùn)算符加粗并更改顏色 ? ? ? ? ? ? ? ? ? ? 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. 計(jì)算器功能設(shè)計(jì)
設(shè)置監(jiān)聽
設(shè)兩個(gè)空字符串,一個(gè)用來保存表達(dá)式,另一個(gè)用來保存歷史記錄
為所有按鍵設(shè)置監(jiān)聽功能,將輸入的表達(dá)式顯示到文本框的右邊,并實(shí)現(xiàn)計(jì)算結(jié)果,查看歷史記錄,清空歷史記錄,計(jì)算器表達(dá)式退格功能,判斷表達(dá)式合法性.
@Override public void actionPerformed(ActionEvent e) { ? //監(jiān)聽功能 ? ? ? ? ? ? String strings = e.getActionCommand();//保存記錄 ? ? ? ? ? ? //JOptionPane.showMessageDialog(this,strings);//監(jiān)聽 ? ? ? ? ? ? ? if ("0123456789".contains(strings)) { ? ? ? ? ? ? ? ? if (Objects.equals(firstint, "")) { //輸入新的表達(dá)式,清除掉上一個(gè)表達(dá)式結(jié)果 ? ? ? ? ? ? ? ? ? ? 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)==')'){ ?//)后輸入數(shù)字補(bǔ)*號(hào) ? ? ? ? ? ? ? ? ? ? firstint+="*"+strings; ? ? ? ? ? ? ? ? ? ? this.input_text.setText(firstint); ? ? ? ? ? ? ? ? }else {this.input_text.setText(input_text.getText() + strings);//將輸入的數(shù)記錄并將之前的數(shù)放到前面 ? ? ? ? ? ? ? ? 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); //自帶補(bǔ)0 ? ? ? ? ? ? ? ? ? ? firstint = "0" + strings;} ? ? ? ? ? ? ? ? } else if(firstint.charAt(firstint.length() - 1) == ')'){ //)后輸入小數(shù)點(diǎn)補(bǔ)0 ? ? ? ? ? ? ? ? ? ? firstint =firstint+ "*0"+strings; ? ? ? ? ? ? ? ? ? ? this.input_text.setText(firstint); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? else if (firstint.charAt(firstint.length() - 1) == '.') { ? //不能連續(xù)小數(shù)點(diǎn) ? ? ? ? ? ? ? ? ? ? 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); ?//前一個(gè)既不是數(shù)字也不是小數(shù)補(bǔ)0 ? ? ? ? ? ? ? ? ? ? this.input_text.setHorizontalAlignment(JTextField.RIGHT); ? ? ? ? ? ? ? ? ? ? firstint = firstint + "0" + strings; ? ? ? ? ? ? ? ? } else if (ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length() - 1)))) {//如果前面是數(shù)字之間輸入 ? ? ? ? ? ? ? ? ? ? int count = 0, i = 0; ? ? ? ? ? ? ? ? ? ? for (i = firstint.length() - 1; i > 0; i--) { ? ? //查找前面的數(shù)字串中有沒有小數(shù)點(diǎn) ? ? ? ? ? ? ? ? ? ? ? ? if (ToPolland.isSymbol(String.valueOf(firstint.charAt(i)))) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? }//直到遇到下一個(gè)運(yùn)算符時(shí)結(jié)束查找 ? ? ? ? ? ? ? ? ? ? ? ? else if (firstint.charAt(i) == '.') { ? ? ? ? ? ? ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? if (count == 0) { ? ? ?//判斷前面的數(shù)字串沒有小數(shù)點(diǎn) ? ? ? ? ? ? ? ? ? ? ? ? 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, "")) { //運(yùn)算符前必須有運(yùn)算數(shù) ? ? ? ? ? ? ? ? ? ? if (!Objects.equals(ans, "")) { ? ? ? ? ? ? ? ? ? ? ? ? firstint += ans+strings; ? ? ? ? ? ? ? ? ? ? ? ? this.input_text.setText(firstint); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? if(strings.equals("-")){ ? //減號(hào)第一個(gè)輸入當(dāng)做負(fù)號(hào) ? ? ? ? ? ? ? ? ? ? ? ? this.input_text.setHorizontalAlignment(JTextField.RIGHT); ? ? ? ? ? ? ? ? ? ? ? ? this.input_text.setText("-"); ? ? ? ? ? ? ? ? ? ? ? ? firstint += strings; ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? //JOptionPane.showMessageDialog(null, "請(qǐng)先輸入操作數(shù)"); ? ? ? ? ? ? ? ? }else if(firstint.charAt(firstint.length()-1)=='.'){ ?//小數(shù)點(diǎn)后不能跟運(yùn)算符 ? ? ? ? ? ? ? ? ? ? this.input_text.setText(firstint); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? else if (firstint.charAt(firstint.length() - 1)=='('){ //(后只能跟-號(hào)運(yùn)算符 ? ? ? ? ? ? ? ? ? ? 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++) { ?//找出()的個(gè)數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (firstint.charAt(i) == '(') { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count1++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? ? ? if (firstint.charAt(i) == ')') { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? count2++; ? ? ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? ? ? if (count1 >= count2) { ?(個(gè)數(shù)必須大于等于)個(gè)數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? this.input_text.setText(input_text.getText() + strings); ? ? ? ? ? ? ? ? ? ? ? ? ? ? firstint = firstint + strings; ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println(firstint); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? } ? ? ? ? ? ? } else if (strings.equals("=")) { ? //計(jì)算結(jié)果 ? ? ? ? ? ? ? ? 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("算式表達(dá)式:" + firstint); ? ? ? ? ? ? ? ? ? ? System.out.println("轉(zhuǎn)逆波蘭表達(dá)式:" + builder); ? ? ? ? ? ? ? ? ? ? System.out.println("轉(zhuǎn)逆波蘭表達(dá)式計(jì)算結(jié)果:" + 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, "表達(dá)式錯(cuò)誤"); ? ? ? ? ? ? ? ? ? ? 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")) { ? //清空當(dāng)前記錄 ? ? ? ? ? ? ? ? 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())); ? ? ? ? ? ? } ? ? ? ? } ? ? }
二、表達(dá)式求值
1、將中綴表達(dá)式轉(zhuǎn)為 list 結(jié)構(gòu)
中綴轉(zhuǎn)后綴表達(dá)式時(shí)需要先將中綴表達(dá)式轉(zhuǎn)為 list 結(jié)構(gòu),在這個(gè)過程中,可以分析表達(dá)式的合理性,將表達(dá)式進(jìn)行處理(去掉空格及其他錯(cuò)誤的符號(hào)),判斷表達(dá)式的正確性并給予反饋 . 我們處理的時(shí)候還需要注意多位數(shù)字的處理,可以利用一個(gè)字符數(shù)組對(duì)多位數(shù)字和小數(shù)進(jìn)行拼接
//將表達(dá)式存入list public static List<String> toList(String strings) { ? ? ? ? strings = tList(strings); ? ? ? ? if (strings == null || strings.length() <= 0) { ? ? ? ? ? ? throw new NullPointerException("表達(dá)式不能為空!"); ? ? ? ? } ? ? ? ? // 去掉不合法的符號(hào) ? ? ? ? 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++) { ? ? ? ? ? ? // 判斷是否是數(shù)字 ? ? ? ? ? ? if (!Character.isDigit((chars[i]))) { ? ? ? ? ? ? ? ? list.add(String.valueOf(chars[i])); ? ? ? ? ? ? } else { ?//如果是數(shù)字,就判斷下一個(gè)是不是數(shù)字,如果是就進(jìn)行組合(循環(huán)),然后錄入list ? ? ? ? ? ? ? ? do { ? ? ? ? ? ? ? ? ? ? ch = String.valueOf(chars[i]); ? ?//讀取一個(gè)字符 ? ? ? ? ? ? ? ? ? ? str += ch; ? ? ? ? ? ? ?//進(jìn)行拼接 ? ? ? ? ? ? ? ? ? ? i++; ? ? ? ? ? ? ? ? ? ? //不是最后一個(gè)字符,并且下一個(gè)還是數(shù)字或者小數(shù)點(diǎn),就進(jìn)行循環(huán) ? ? ? ? ? ? ? ? } 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; ? ? }
需要注意的是當(dāng)輸入的表達(dá)式中存在負(fù)數(shù)時(shí),需要在負(fù)號(hào)前面補(bǔ)0,或者將負(fù)號(hào)后面的表達(dá)式中的一個(gè)計(jì)算符取反,否則轉(zhuǎn)為逆波蘭表達(dá)式后得不到正確的結(jié)果。
//表達(dá)式中存在負(fù)數(shù)時(shí),后面的逆波蘭表達(dá)式算法無法得到正確結(jié)果,需要補(bǔ)0 public static String tList(String strings) { ? ? ? ? String stringBuilder = ""; ? ? ? ? if(strings.charAt(0)=='-'){//如果第一個(gè)字符是‘-',在負(fù)號(hào)前面補(bǔ)0 ? ? ? ? ? ? stringBuilder+= "0"; ? ? ? ? } ? ? ? ? stringBuilder+=strings.charAt(0); //將第一個(gè)‘-'號(hào)接到0后面 ? ? ? ? //如果遇到負(fù)號(hào),并且負(fù)號(hào)前面的符號(hào)不是數(shù)字,在負(fù)號(hào)前面補(bǔ)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);//沒有負(fù)號(hào)則直接拼接 ? ? ? ? } ? ? ? ? return stringBuilder; ? ? }
2、逆波蘭表達(dá)式的轉(zhuǎn)化(單棧法)
采用單棧來和一個(gè)隊(duì)列對(duì)表達(dá)式進(jìn)行操作,也可以采用雙棧法處理表達(dá)式
構(gòu)造判斷數(shù)字,計(jì)算符以及優(yōu)先級(jí)的方法
?
實(shí)現(xiàn)代碼如下:
//轉(zhuǎn)逆波蘭表達(dá)式 public static List<String> toPolland(List<String> list) { ? ? ? ? Stack<String> s1 = new Stack(); ? ? ? ? List<String> s2 = new ArrayList<>(); ? ? ? ? ? // ?從左至右掃描中綴表達(dá)式; ? ? ? ? for (String item : list) { ? ? ? ? ? ? // 遇到操作數(shù)時(shí),將其壓s2; ? ? ? ? ? ? if (Pattern.matches("-?[0-9]+(\\.[0-9]+)?", item)) { ? ? ? ? ? ? ? ? s2.add(item); ? ? ? ? ? ? }//遇到操作符時(shí),比較其與棧頂?shù)牟僮鞣膬?yōu)先級(jí) ? ? ? ? ? ? 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("(")) { //右括號(hào)直接入棧 ? ? ? ? ? ? ? ? s1.push(item); ? ? ? ? ? ? } ? ? ? ? ? ? if (item.equals(")")) { ?//遇到右括號(hào),將左括號(hào)之前的操作符全部出棧 ? ? ? ? ? ? ? ? while (!s1.peek().equals("(")) { ? ? ? ? ? ? ? ? ? ? s2.add(s1.pop()); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? // 將左邊的括號(hào),彈棧 ? ? ? ? ? ? ? ? s1.pop(); ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? while (s1.size() > 0) { ?//將剩余的操作符全部入棧 ? ? ? ? ? ? s2.add(s1.pop()); ? ? ? ? } ? ? ? ? return s2; ? ? }
判斷數(shù)字和運(yùn)算符已經(jīng)比較運(yùn)算符優(yōu)先級(jí):
//判斷是否為數(shù)字 public static boolean isNumber(String str) { ? ? ? ? return Pattern.matches("-?[0-9]+(\\.[0-9]+)?", str); ? ? } ? ? //是否是運(yùn)算符 ? ? public static boolean isSymbol(String str) { ? ? ? ? ? ? ? ? return "+-*/".contains(str); ? ? } ? ? //返回運(yùn)算符的優(yōu)先級(jí) ? ? public static int priority(String value) { ? ? ? ? if ("+-".contains(value)) { ? ? ? ? ? ? return 1; ? ? ? ? } else if ("*/".contains(value)) { ? ? ? ? ? ? return 2; ? ? ? ? } else { ? ? ? ? ? ? throw new RuntimeException("暫不支持操作符:" + value); ? ? ? ? } ? ? }
3、逆波蘭表達(dá)式(后綴表達(dá)式)的計(jì)算
首先準(zhǔn)備一個(gè)棧Res_Stack.
1、從左開始向右遍歷后綴表達(dá)式的元素。
2、如果取到的元素是操作數(shù),直接入棧Res_Stack,如果是運(yùn)算符,從棧中彈出2個(gè)數(shù)進(jìn)行運(yùn)算,然后把運(yùn)算結(jié)果入棧
3、當(dāng)遍歷完后綴表達(dá)式時(shí),計(jì)算結(jié)果就保存在棧里了。
算法思想:
代碼如下:
//逆波蘭表達(dá)式的計(jì)算 public static BigDecimal calculate(List<String> nipollands) { ? ? ? ? if (nipollands == null || nipollands.size() <= 1) { ? ? ? ? ? ? throw new NullPointerException("逆波蘭表達(dá)式列表不能為空!"); ? ? ? ? } ? ? ? ? Stack<BigDecimal> stack = new Stack(); ? ? ? ? for (String nipolland : nipollands) { ? ? ? ? ? ? if (isNumber(nipolland)) { ? //數(shù)字直接入棧 ? ? ? ? ? ? ? ? stack.push(new BigDecimal(nipolland)); ? ? ? ? ? ? } else { ? ? ?//遇到操作符取出兩個(gè)數(shù)進(jìn)行對(duì)應(yīng)的計(jì)算,并將計(jì)算結(jié)果入棧 ? ? ? ? ? ? ? ? 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);//遍歷字符串后得到的棧頂既為逆波蘭表達(dá)式計(jì)算結(jié)果 ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? 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("計(jì)算器"); ? ? ? ? ? ? history.setEditable(false); ? ? ? ? ? ? history.setFont(new Font("宋體", Font.PLAIN, 30)); ? ? ? ? ? ? this.setSize(477, 577); //界面大小 ? ? ? ? ? ? this.setLayout(new BorderLayout()); ? ? ? ? ? ? this.setResizable(false); ? ? ? ? ? ? this.setLocationRelativeTo(null); ? //界面位置設(shè)置居中 ? ? ? ? ? ? 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(); ? ? ? ? ? //將界面串聯(lián) ? ? ? ? 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() { ?//為清除操作設(shè)置監(jiān)聽 ? ? ? ? ? ? ? ? @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)) { ? //將運(yùn)算符加粗并更改顏色 ? ? ? ? ? ? ? ? ? ? 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 = "";//保存表達(dá)式 ? ? ? ? static String hitory = "";//保存歷史記錄 ? ? ? ? static String ans = ""; ? ? ? ? ? @Override ? ? ? ? public void actionPerformed(ActionEvent e) { ? //監(jiān)聽功能 ? ? ? ? ? ? String strings = e.getActionCommand();//保存記錄 ? ? ? ? ? ? //JOptionPane.showMessageDialog(this,strings);//監(jiān)聽 ? ? ? ? ? ? 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);//將輸入的數(shù)記錄并將之前的數(shù)放到前面 ? ? ? ? ? ? ? ? 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) == '.') { ? //不能連續(xù)小數(shù)點(diǎn) ? ? ? ? ? ? ? ? ? ? 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); ?//前一個(gè)既不是數(shù)字也不是小數(shù)補(bǔ)0 ? ? ? ? ? ? ? ? ? ? this.input_text.setHorizontalAlignment(JTextField.RIGHT); ? ? ? ? ? ? ? ? ? ? firstint = firstint + "0" + strings; ? ? ? ? ? ? ? ? } else if (ToPolland.isNumber(String.valueOf(firstint.charAt(firstint.length() - 1)))) {//如果前面是數(shù)字之間輸入 ? ? ? ? ? ? ? ? ? ? int count = 0, i = 0; ? ? ? ? ? ? ? ? ? ? for (i = firstint.length() - 1; i > 0; i--) { ? ? //查找前面的數(shù)字串中有沒有小數(shù)點(diǎn) ? ? ? ? ? ? ? ? ? ? ? ? if (ToPolland.isSymbol(String.valueOf(firstint.charAt(i)))) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? break; ? ? ? ? ? ? ? ? ? ? ? ? }//直到遇到下一個(gè)運(yùn)算符時(shí)結(jié)束查找 ? ? ? ? ? ? ? ? ? ? ? ? else if (firstint.charAt(i) == '.') { ? ? ? ? ? ? ? ? ? ? ? ? ? ? count++; ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? if (count == 0) { ? ? ?//判斷前面的數(shù)字串沒有小數(shù)點(diǎn) ? ? ? ? ? ? ? ? ? ? ? ? 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, "請(qǐng)先輸入操作數(shù)"); ? ? ? ? ? ? ? ? } else if (ToPolland.isSymbol(String.valueOf(firstint.charAt(firstint.length() - 1)))&&strings!="-") { ? ? ? ? ? ? ? ? ? ? JOptionPane.showMessageDialog(null, "表達(dá)式錯(cuò)誤"); ? ? ? ? ? ? ? ? } 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("=")) { ? //計(jì)算結(jié)果 ? ? ? ? ? ? ? ? try { ? ? ? ? ? ? ? ? ? ? System.out.println(firstint); ? ? ? ? ? ? ? ? ? ? StringBuilder builder = new StringBuilder(); ? ? ? ? ? ? ? ? ? ? List<String> list = toPolland(ToPolland.toList(firstint)); ? ? ? ? ? ? ? ? ? ? list.forEach(builder::append); ? ? ? ? ? ? ? ? ? ? System.out.println("算式表達(dá)式:" + firstint); ? ? ? ? ? ? ? ? ? ? System.out.println("轉(zhuǎn)逆波蘭表達(dá)式:" + builder); ? ? ? ? ? ? ? ? ? ? System.out.println("轉(zhuǎn)逆波蘭表達(dá)式計(jì)算結(jié)果:" + 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, "表達(dá)式錯(cuò)誤"); ? ? ? ? ? ? ? ? ? ? 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")) { ? //清空當(dāng)前記錄 ? ? ? ? ? ? ? ? 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 { ? ? //表達(dá)式中存在負(fù)數(shù)時(shí),后面的逆波蘭表達(dá)式算法無法得到正確結(jié)果,需要補(bǔ)0 ? ? public static String tList(String strings) { ? ? ? ? String stringBuilder = ""; ? ? ? ? if(strings.charAt(0)=='-'){//如果第一個(gè)字符是‘-',在負(fù)號(hào)前面補(bǔ)0 ? ? ? ? ? ? stringBuilder+= "0"; ? ? ? ? } ? ? ? ? stringBuilder+=strings.charAt(0); //將第一個(gè)‘-'號(hào)接到0后面 ? ? ? ? //如果遇到負(fù)號(hào),并且負(fù)號(hào)前面的符號(hào)不是數(shù)字,在負(fù)號(hào)前面補(bǔ)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);//沒有負(fù)號(hào)則直接拼接 ? ? ? ? } ? ? ? ? return stringBuilder; ? ? } ? ? //將表達(dá)式存入list ? ? public static List<String> toList(String strings) { ? ? ? ? strings = tList(strings); ? ? ? ? if (strings == null || strings.length() <= 0) { ? ? ? ? ? ? throw new NullPointerException("表達(dá)式不能為空!"); ? ? ? ? } ? ? ? ? // 去掉不合法的符號(hào) ? ? ? ? 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++) { ? ? ? ? ? ? // 判斷是否是數(shù)字 ? ? ? ? ? ? if (!Character.isDigit((chars[i]))) { ? ? ? ? ? ? ? ? list.add(String.valueOf(chars[i])); ? ? ? ? ? ? } else { ?//如果是數(shù)字,就判斷下一個(gè)是不是數(shù)字,如果是就進(jìn)行組合(循環(huán)),然后錄入list ? ? ? ? ? ? ? ? do { ? ? ? ? ? ? ? ? ? ? ch = String.valueOf(chars[i]); ? ?//讀取一個(gè)字符 ? ? ? ? ? ? ? ? ? ? str += ch; ? ? ? ? ? ? ?//進(jìn)行拼接 ? ? ? ? ? ? ? ? ? ? i++; ? ? ? ? ? ? ? ? ? ? //不是最后一個(gè)字符,并且下一個(gè)還是數(shù)字或者小數(shù)點(diǎn),就進(jìn)行循環(huán) ? ? ? ? ? ? ? ? } 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; ? ? } ? ? //轉(zhuǎn)逆波蘭表達(dá)式 ? ? public static List<String> toPolland(List<String> list) { ? ? ? ? Stack<String> s1 = new Stack(); ? ? ? ? List<String> s2 = new ArrayList<>(); ? ? ? ? // ?從左至右掃描中綴表達(dá)式; ? ? ? ? for (String item : list) { ? ? ? ? ? ? // 遇到操作數(shù)時(shí),將其壓s2; ? ? ? ? ? ? if (Pattern.matches("-?[0-9]+(\\.[0-9]+)?", item)) { ? ? ? ? ? ? ? ? s2.add(item); ? ? ? ? ? ? }//遇到操作符時(shí),比較其與棧頂?shù)牟僮鞣膬?yōu)先級(jí) ? ? ? ? ? ? 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("(")) { //右括號(hào)直接入棧 ? ? ? ? ? ? ? ? s1.push(item); ? ? ? ? ? ? } ? ? ? ? ? ? if (item.equals(")")) { ?//遇到右括號(hào),將左括號(hào)之前的操作符全部出棧 ? ? ? ? ? ? ? ? while (!s1.peek().equals("(")) { ? ? ? ? ? ? ? ? ? ? s2.add(s1.pop()); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? s1.pop();// 將左邊的括號(hào),彈棧 ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? while (s1.size() > 0) { ?//將剩余的操作符全部入棧 ? ? ? ? ? ? s2.add(s1.pop()); ? ? ? ? } ? ? ? ? return s2; ? ? } ? ? //逆波蘭表達(dá)式的計(jì)算 ? ? public static BigDecimal calculate(List<String> nipollands) { ? ? ? ? if (nipollands == null || nipollands.size() <= 1) { ? ? ? ? ? ? throw new NullPointerException("逆波蘭表達(dá)式列表不能為空!"); ? ? ? ? } ? ? ? ? Stack<BigDecimal> stack = new Stack(); ? ? ? ? for (String nipolland : nipollands) { ? ? ? ? ? ? if (isNumber(nipolland)) { ? //數(shù)字直接入棧 ? ? ? ? ? ? ? ? stack.push(new BigDecimal(nipolland)); ? ? ? ? ? ? } else { ? ? ?//遇到操作符取出兩個(gè)數(shù)進(jìn)行對(duì)應(yīng)的計(jì)算,并將計(jì)算結(jié)果入棧 ? ? ? ? ? ? ? ? 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);//遍歷字符串后得到的棧頂既為逆波蘭表達(dá)式計(jì)算結(jié)果 ? ? ? ? ? ? } ? ? ? ? } ? ? ? ? return stack.pop(); ? ? } ? ? //判斷是否為數(shù)字 ? ? public static boolean isNumber(String str) { ? ? ? ? return Pattern.matches("-?[0-9]+(\\.[0-9]+)?", str); ? ? } ? ? //是否是運(yùn)算符 ? ? public static boolean isSymbol(String str) { ? ? ? ? return "+-*/".contains(str); ? ? } ? ? //返回運(yùn)算符的優(yōu)先級(jí) ? ? public static int priority(String value) { ? ? ? ? if ("+-".contains(value)) { ? ? ? ? ? ? return 1; ? ? ? ? } else if ("*/".contains(value)) { ? ? ? ? ? ? return 2; ? ? ? ? } else { ? ? ? ? ? ? throw new RuntimeException("暫不支持操作符:" + value); ? ? ? ? } ? ? } }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Spring Boot 在啟動(dòng)時(shí)進(jìn)行配置文件加解密的方法詳解
這篇文章主要介紹了Spring Boot 在啟動(dòng)時(shí)進(jìn)行配置文件加解密的方法,本文通過實(shí)例給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-06-06一文了解Java Log框架徹底搞懂Log4J,Log4J2,LogBack,SLF4J
本文主要介紹了一文了解Java Log框架徹底搞懂Log4J,Log4J2,LogBack,SLF4J,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-03-03詳解Java中多線程異常捕獲Runnable的實(shí)現(xiàn)
這篇文章主要介紹了詳解Java中多線程異常捕獲Runnable的實(shí)現(xiàn)的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這樣的知識(shí),需要的朋友可以參考下2017-10-10