欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java實(shí)現(xiàn)簡易計(jì)算器(逆波蘭表達(dá)式)

 更新時(shí)間:2022年07月21日 15:06:48   作者:Eren·Yeager-  
這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)簡易計(jì)算器,逆波蘭表達(dá)式,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(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)行配置文件加解密的方法詳解

    這篇文章主要介紹了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

    本文主要介紹了一文了解Java Log框架徹底搞懂Log4J,Log4J2,LogBack,SLF4J,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-03-03
  • Java中的@SneakyThrows注解詳解

    Java中的@SneakyThrows注解詳解

    這篇文章主要介紹了Java中的@SneakyThrows注解詳解,@SneakyThrows將當(dāng)前方法拋出的異常,包裝成RuntimeException,騙過編譯器,使得調(diào)用點(diǎn)可以不用顯示處理異常信息,需要的朋友可以參考下
    2023-10-10
  • java 迭代器模式實(shí)例詳解

    java 迭代器模式實(shí)例詳解

    這篇文章主要介紹了java 迭代器模式實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • java實(shí)現(xiàn)上傳文件到FTP

    java實(shí)現(xiàn)上傳文件到FTP

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)上傳文件到FTP,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • SpringBoot整合MongoDB的示例

    SpringBoot整合MongoDB的示例

    這篇文章主要介紹了SpringBoot整合MongoDB的示例,幫助大家更好的理解和學(xué)習(xí)springboot框架,感興趣的朋友可以了解下
    2020-10-10
  • 詳解Java中多線程異常捕獲Runnable的實(shí)現(xiàn)

    詳解Java中多線程異常捕獲Runnable的實(shí)現(xiàn)

    這篇文章主要介紹了詳解Java中多線程異常捕獲Runnable的實(shí)現(xiàn)的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解掌握這樣的知識(shí),需要的朋友可以參考下
    2017-10-10
  • 通過實(shí)例解析Java class文件編譯加載過程

    通過實(shí)例解析Java class文件編譯加載過程

    這篇文章主要介紹了通過實(shí)例解析Java class文件編譯加載過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • Java中ArrayList刪除的常用操作及方法

    Java中ArrayList刪除的常用操作及方法

    ArrayList是最常用的一種java集合,在開發(fā)中我們常常需要從ArrayList中刪除特定元素,本文主要介紹了Java中ArrayList刪除的常用操作及方法,感興趣的可以了解一下
    2023-11-11
  • Spring BeanUtils忽略空值拷貝的方法示例代碼

    Spring BeanUtils忽略空值拷貝的方法示例代碼

    本文用示例介紹Spring(SpringBoot)如何使用BeanUtils拷貝對(duì)象屬性忽略空置,忽略null值拷貝屬性的用法,代碼簡單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2022-03-03

最新評(píng)論