您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關利用Java編寫一個簡單的計算器,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
1、:輸入,輸出
輸入:允許輸入帶有括號的完整計算式(例 8*(4-95)+5÷2*e-pi)
輸出:輸出Double類型的結果
輸出:整個運算表達式并保存于歷史記錄中
2、:功能
基本的加,減,乘,除,四則運算
平方運算
開方運算
求余運算
最終界面如下圖:
除了常規的數字按鈕和運算符,還有兩個常數e,pi(π),清空鍵AC,括號運算符(),平方(x^x)和開方(sqrt)運算符,輸入顯示框以及歷史記錄文本框,文本框的垂直滾動條和水平滾動條。
1:中綴表達式轉為后綴表達式
準備:
①后綴表達式隊列:postQueue,用于存儲逆波蘭表達式(其實不用隊列排序直接輸出也行)
②操作符棧:opStack,對用戶輸入的操作符進行處理,用于存儲運算符
算法思想:
從左向右依次讀取算術表達式的元素X,分以下情況進行不同的處理:
(1)如果X是操作數,直接入隊
(2)如果X是運算符,再分以下情況:
a)如果棧為空,直接入棧。
b)如果X==”(“,直接入棧。
c)如果X==”)“,則將棧里的元素逐個出棧,并入隊到后綴表達式隊列中,直到第一個配對的”(”出棧。(注:“(”和“)”都不 入隊)
d)如果是其他操作符(+ - * /),則和棧頂元素進行比較優先級。 如果棧頂元素的優先級大于等于X,則出棧并把棧中彈出的元素入隊,直到棧頂元素的優先級小于X或者棧為空。彈出完這些元素后,才將遇到的操作符壓入到棧中。
(3)最后將棧中剩余的操作符全部入隊。
示意圖:
2、計算后綴表達式
準備:
需要用到一個結果棧Res_Stack :用于存放計算的中間過程的值和最終結果
算法思想:
1、從左開始向右遍歷后綴表達式的元素。
2、如果取到的元素是操作數,直接入棧Res_Stack,如果是運算符,從棧中彈出2個數進行運算,然后把運算結果入棧
3、當遍歷完后綴表達式時,計算結果就保存在棧里了。
示意圖:
分析:
1、可實現基本四則運算及平方、開方、求余運算。
2、運算表達式可顯示于輸入界面并保存于歷史記錄欄
3、輸入界面和歷史記錄欄皆可實現不斷字自動換行功能以及滾動條功能
4、不足之處:進行平方和開方運算時其保存在歷史記錄中的表達式會出現兩個等號及兩個結果。
package software; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; //Calculator類,繼承JFrame框架,實現事件監聽器接口 public class Calculator extends JFrame implements ActionListener { private String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt", "%", "x*x", "*", "(", ")", ".", "=" }; private JButton keys[] = new JButton[KEYS.length]; private JTextArea resultText = new JTextArea("0.0");// 文本域組件TextArea可容納多行文本;文本框內容初始值設為0.0 private JTextArea History = new JTextArea();// 歷史記錄文本框初始值設為空 private JPanel jp1=new JPanel(); private JPanel jp2=new JPanel(); private JScrollPane gdt1=new JScrollPane(resultText);//給輸入顯示屏文本域新建一個垂直滾動滑條 private JScrollPane gdt2=new JScrollPane(History);//給歷史記錄文本域新建一個垂直滾動滑條 // private JScrollPane gdt3=new JScrollPane(History);//給歷史記錄文本域新建一個水平滾動滑條 private JLabel label = new JLabel("歷史記錄"); private String b = ""; // 構造方法 public Calculator() { super("Caculator");//“超”關鍵字,表示調用父類的構造函數, resultText.setBounds(20, 18, 255, 115);// 設置文本框大小 resultText.setAlignmentX(RIGHT_ALIGNMENT);// 文本框內容右對齊 resultText.setEditable(false);// 文本框不允許修改結果 History.setBounds(290, 40, 250,370);// 設置文本框大小 History.setAlignmentX(LEFT_ALIGNMENT);// 文本框內容右對齊 History.setEditable(false);// 文本框不允許修改結果 label.setBounds(300, 15, 100, 20);//設置標簽位置及大小 jp2.setBounds(290,40,250,370);//設置面板窗口位置及大小 jp2.setLayout(new GridLayout()); jp1.setBounds(20,18,255,115);//設置面板窗口位置及大小 jp1.setLayout(new GridLayout()); resultText.setLineWrap(true);// 激活自動換行功能 resultText.setWrapStyleWord(true);// 激活斷行不斷字功能 resultText.setSelectedTextColor(Color.RED); History.setLineWrap(true);//自動換行 History.setWrapStyleWord(true); History.setSelectedTextColor(Color.blue); gdt1.setViewportView(resultText);//使滾動條顯示出來 gdt2.setViewportView(History); gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//設置讓垂直滾動條一直顯示 gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//設置讓垂直滾動條一直顯示 gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);//設置讓水平滾動條一直顯示 jp1.add(gdt1);//將滾動條添加入面板窗口中 jp2.add(gdt2); this.add(jp1);//將面板添加到總窗體中 this.add(jp2);//將面板添加到總窗體中 this.setLayout(null); this.add(label);// 新建“歷史記錄”標簽 //this.add(resultText);// 新建文本框,該語句會添加進去一個新的JTextArea導致帶有滾動條的文本無法顯示或者發生覆蓋 //this.add(History);// 新建歷史記錄文本框,該語句會添加進去一個新的JTextArea導致帶有滾動條的文本無法顯示 // 放置按鈕 int x = 20, y = 150; for (int i = 0; i < KEYS.length; i++) { keys[i] = new JButton(); keys[i].setText(KEYS[i]); keys[i].setBounds(x, y, 60, 40); if (x < 215) { x += 65; } else { x = 20; y += 45; } this.add(keys[i]); } for (int i = 0; i < KEYS.length; i++)// 每個按鈕都注冊事件監聽器 { keys[i].addActionListener(this); } this.setResizable(false); this.setBounds(500, 200, 567, 480); this.setDefaultCloseOperation(EXIT_ON_CLOSE); this.setVisible(true); } // 事件處理 public void actionPerformed(ActionEvent e) { //History.setText(b);//使輸入的表達式顯示在歷史記錄文本框中 String label=e.getActionCommand();//獲得事件源的標簽 if(label=="=")// { resultText.setText(this.b); History.setText(History.getText()+resultText.getText()); if(label=="=")//調用計算方法,得出最終結果 { String s[]=houzhui(this.b); String result=Result(s); this.b=result+""; //更新文本框,當前結果在字符串b中,并未刪除,下一次輸入接著此結果以實現連續運算 resultText.setText(this.b); History.setText(History.getText()+"="+resultText.getText()+"\n"); } } else if(label=="AC")//清空按鈕,消除顯示屏文本框前面所有的輸入和結果 { this.b=""; resultText.setText("0");//更新文本域的顯示,顯示初始值; } else if(label=="sqrt") { String n=kfys(this.b); resultText.setText("sqrt"+"("+this.b+")"+"="+n);//使運算表達式顯示在輸入界面 History.setText(History.getText()+"sqrt"+"("+this.b+")"+"=");//獲取輸入界面的運算表達式并使其顯示在歷史記錄文本框 this.b=n; } else if(label=="x*x") { String m=pfys(this.b); resultText.setText(this.b+"^2"+"="+m);//使運算表達式顯示在輸入界面 History.setText(History.getText()+this.b+"^2"+"=");//獲取輸入界面的運算表達式并使其顯示在歷史記錄文本框 this.b=m; } else if(label=="e"||label=="pi") { if(label=="e") { String m=String.valueOf(2.71828);//將e的值以字符串的形式傳給m this.b=this.b+m;//保留顯示m之前輸入的運算符或數字字符繼續下一步運算 resultText.setText(this.b); // History.setText(History.getText()+this.b); } if(label=="pi") { String m=String.valueOf(3.14159265); this.b=this.b+m; resultText.setText(this.b); // History.setText(History.getText()+this.b); } } else { this.b=this.b+label; resultText.setText(this.b); // History.setText(History.getText()+this.b); } //History.setText(History.getText()+this.b);//使輸入的表達式顯示在歷史記錄文本框中 } //將中綴表達式轉換為后綴表達式 private String[] houzhui(String str) { String s = "";// 用于承接多位數的字符串 char opStack[] = new char[100];// 靜態棧,對用戶輸入的操作符進行處理,用于存儲運算符 String postQueue[] = new String[100];// 后綴表達式字符串數組,為了將多位數存儲為獨立的字符串 int top = -1, j = 0;// 靜態指針top,控制變量j for (int i = 0; i < str.length(); i++)// 遍歷中綴表達式 // indexof函數,返回字串首次出現的位置;charAt函數返回index位置處的字符; { if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到數字字符的情況 { s = "";// 作為承接字符,每次開始時都要清空 for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) { s = s + str.charAt(i); } i--; postQueue[j] = s;// 數字字符直接加入后綴表達式 j++; } else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括號 top++; opStack[top] = str.charAt(i);// 左括號入棧 } else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括號 for (;;)// 棧頂元素循環出棧,直到遇到左括號為止 { if (opStack[top] != '(') {// 棧頂元素不是左括號 postQueue[j] = opStack[top] + "";// 棧頂元素出棧 j++; top--; } else { // 找到棧頂元素是左括號 top--;// 刪除棧頂左括號 break;// 循環結束 } } } if ("*%/".indexOf(str.charAt(i)) >= 0)// 遇到高優先級運算符 { if (top == -1) {// 若棧為空則直接入棧 top++; opStack[top] = str.charAt(i); } else {// 棧不為空,把棧中彈出的元素入隊,直到棧頂元素優先級小于x或者棧為空 if ("*%/".indexOf(opStack[top]) >= 0) { // 棧頂元素也為高優先級運算符 postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后綴表達式 j++; opStack[top] = str.charAt(i);// 當前運算符入棧 } else if ("(".indexOf(opStack[top]) >= 0) {// 棧頂元素為左括號,當前運算符入棧 top++; opStack[top] = str.charAt(i); } else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低優先級運算符 postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后最表達式 j++; opStack[top] = str.charAt(i);// 當前元素入棧 } } } else if ("+-".indexOf(str.charAt(i)) >= 0) { if (top == -1) { top++; opStack[top] = str.charAt(i); } else { if ("*%/".indexOf(opStack[top]) >= 0) { // 棧頂元素也為高優先級運算符 postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后綴表達式 j++; opStack[top] = str.charAt(i);// 當前運算符入棧 } else if ("(".indexOf(opStack[top]) >= 0) {// 棧頂元素為左括號,當前運算符入棧 top++; opStack[top] = str.charAt(i); } else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低優先級運算符 postQueue[j] = opStack[top] + "";// 棧頂元素出棧進入后最表達式 j++; opStack[top] = str.charAt(i);// 當前元素入棧 } } } } for (; top != -1;) {// 遍歷結束后將棧中剩余元素依次出棧進入后綴表達式 postQueue[j] = opStack[top] + ""; j++; top--; } return postQueue; } //開方運算方法 public String kfys(String str) { String result = ""; double a = Double.parseDouble(str), b = 0; b = Math.sqrt(a); result = String.valueOf(b);//將運算結果轉換為string類型并賦給string類型的變量result return result; } //平方運算方法 public String pfys(String str) { String result = ""; double a = Double.parseDouble(str), b = 0; b = Math.pow(a, 2); result = String.valueOf(b); return result; } // 計算后綴表達式,并返回最終結果 public String Result(String str[]) { String Result[] = new String[100];// 順序存儲的棧,數據類型為字符串 int Top = -1;// 靜態指針Top for (int i = 0; str[i] != null; i++) { if ("+-*%/".indexOf(str[i]) < 0) { Top++; Result[Top] = str[i]; } if ("+-*%/".indexOf(str[i]) >= 0)// 遇到運算符字符,將棧頂兩個元素出棧計算并將結果返回棧頂 { double x, y, n; x = Double.parseDouble(Result[Top]);// 順序出棧兩個數字字符串,并轉換為double類型 Top--; y = Double.parseDouble(Result[Top]); Top--; if ("-".indexOf(str[i]) >= 0) { n = y - x; Top++; Result[Top] = String.valueOf(n);// 將運算結果重新入棧 } if ("+".indexOf(str[i]) >= 0) { n = y + x; Top++; Result[Top] = String.valueOf(n);// 將運算結果重新入棧 } if ("*".indexOf(str[i]) >= 0) { n = y * x; Top++; Result[Top] = String.valueOf(n);// 將運算結果重新入棧 } if ("/".indexOf(str[i]) >= 0) { if (x == 0)// 被除數不允許為0 { String s = "error!"; return s; } else { n = y / x; Top++; Result[Top] = String.valueOf(n);// 將運算結果重新入棧 } } if ("%".indexOf(str[i]) >= 0) { if (x == 0)// 被除數不允許為0 { String s = "error!"; return s; } else { n = y % x; Top++; Result[Top] = String.valueOf(n);// 將運算結果重新入棧 } } } } return Result[Top];// 返回最終結果 } // 主函數 public static void main(String[] args) { Calculator a = new Calculator(); } }
上述就是小編為大家分享的利用Java編寫一個簡單的計算器了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。