日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

简单的计算器程序却蕴涵的有趣的数据结构

發布時間:2024/1/1 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 简单的计算器程序却蕴涵的有趣的数据结构 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

????????入門學習java 或者c的時候,加減乘除計算器是必不可少的,switch 配合上+-*/ 完成簡易計算器的制作,再入門點的可以套一個ui架子,完成兩個數字加減乘除,但是對于多個數字的加減乘除來說,程序就比較復雜了。我推薦兩種有趣的算法來完成多個數字的加減乘除,優先級等等。逆波蘭算法和雙棧

逆波蘭算法如下,注釋我也直接嵌入到其中,方便復制的時候理解,下面的算法都是寫的工具類,只需要將參數傳入進去即可!

/*** Date:2021/10/23* Description:代碼版權聲明 實現逆波蘭計算器* 代碼思路* 先將表達式轉換為逆波蘭表達式 步驟如下* 1.如果遇到‘(’ 直接入S1* 2.如果遇到數字直接壓入S2* 3.如果遇到‘)’,將S1棧頂距離最近知道‘(’元素依次彈出并依次壓入S2* 4. 如果遇到符號X , X的優先級大于S1棧頂X壓入S1,X的優先級小于或等于S1棧頂進行如下操作* S1彈出棧頂元素,并壓入S2,直到X優先級大于S1棧頂元素或者該元素為‘(’,再將X壓入S1* 5.遍歷結束之后看S1是否為空,若不為空,依次將S1元素彈出并壓入S2* <p>* <p>* <p>* 逆波蘭表達式計算結果代碼思路如下* <p>* 從左到右依次遍歷 定義一個stack即可* 如果是數字,直接壓棧,* 如果是符號(不是數字),則出棧兩次,第一次出棧定義為b ,第二次出棧a ,然后 a opa b* 棧中剩下一個元素就是結果*/ public class PolandClient {//該字符是否為數字private static boolean isNum(char x) {if (x >= '0' && x <= '9' || x == '.') {return true;} else return false;}//獲取符號的優先級private static int getPor(char opera) {int por = 0;if (opera == '+') {por = 1;}if (opera == '-') {por = 1;}if (opera == '*') {por = 3;}if (opera == '/') {por = 3;}return por;}//逆波蘭表達式轉換public ArrayList<String> getPolandString(String cirString) {Stack<String> s1; //定義兩個棧 一個符號棧S1 一個操作棧S2Stack<String> s2;String cir = cirString;char[] chars = cir.toCharArray(); //將表達式轉換成字節 依次遍歷s1 = new Stack<>();//將棧實例化s2 = new Stack<>();int index = 0;//索引 作用能夠遍歷表達式 1+21+3while (true) { //進行遍歷int index0 = index;//如果數字大于10,就會用到index0 為了后面遇見數字的時候 標志索引StringBuilder stringBuilder = new StringBuilder(); // 多次追加數字 用該類比較方便if (index == cir.length()) { //遍歷到滿足此條件時候 跳出循環 判斷跳出循環break;} else if (isNum(chars[index0])) { //是數字的情況下進行 進行如下操作while (index0 != cir.length() && isNum(chars[index0])) {//后面那個還是數字進行如下操作//是數字的話追加stringBuilder.append(chars[index0]); //追加index++;//指標后移index0++;//后移}index--;s2.push(stringBuilder.toString());//將結果入棧} else if (chars[index] == '(') {//如果遍歷到的字符是左括號stringBuilder.append(chars[index]);//追加s1.push(stringBuilder.toString());//入棧 StringBuilder} else if (chars[index] == ')') {//如果遍歷到的字符是右括號 進行如下操作while (true) {//將s1元素出棧,并入s2棧,(前提條件是如若s1出棧的符號是左括號,就將左括號出棧,循環結束)(s1為空棧 同樣結束循環)if (!s1.isEmpty()) {//如果s1不是空的String pop = s1.pop();//出棧 判斷if (pop.equals("(")) {//若它是左括號 循環結束break;} else {//否則 入s2棧s2.push(pop);}} else {break;}}//如下是 遍歷到運算符的時候} else if (chars[index] == '+' || chars[index] == '-' || chars[index] == '*' || chars[index] == '/') {if (s1.isEmpty() || getPor(chars[index]) > getPor(s1.peek().toCharArray()[0])) {//如果s1為空或者該優先級大于S1棧頂優先級stringBuilder.append(chars[index]);//追加s1.push(stringBuilder.toString());//s1入棧 //"1-2/2*3+4" // System.out.println(stringBuilder.toString()+"我的-號");} else if (getPor(chars[index]) <= getPor(s1.peek().toCharArray()[0])) {//如果該優先級 小于等于s1中優先級,進行如下操作while (true) {if (!s1.isEmpty()) {//先判斷是否為空String pop = s1.pop(); //彈出S1棧頂元素if (pop.equals("(") || getPor(chars[index]) > getPor(pop.toCharArray()[0])) {//判斷出棧元素是否為左括號 是s1.push(pop);break;} else if (getPor(chars[index]) <= getPor(pop.toCharArray()[0])) {s2.push(pop); //否則入S2System.out.println(pop);}} else {break;}}stringBuilder.append(chars[index]);s1.push(stringBuilder.toString());}}index++;//索引后移}//遍歷結束后 對S1判空循環 依次將S1元素彈出并壓入S2while (!s1.isEmpty()) {String pop = s1.pop();s2.push(pop);}//最后s2依次彈出放S1 ,這樣s1出棧的順序就是原表達式的后綴表示了(逆波蘭)ArrayList<String> list = new ArrayList<>();//實例化了一個返回集合while (!s2.isEmpty()) {list.add(s2.pop()); // 12 21逆序}Collections.reverse(list);System.out.println(Arrays.asList(list));return list;}//ab+cd- 將逆波蘭表達式轉 計算出結果public double getAnswer(ArrayList<String> list) {//參數是 逆波蘭棧Stack<String> s1 = new Stack<>();for (int i = 0; i < list.size(); i++) {String c = list.get(i); //運算棧if (isNum(c.toCharArray()[0])) {s1.push(c);} else {String second = s1.pop();//2String first = s1.pop();//1double answer = getAnswer(Double.parseDouble(first), Double.parseDouble(second), c);s1.push(answer + "");}}if (!s1.isEmpty()) {String pop = s1.pop();return Double.parseDouble(pop);} else {return 0;}}public double getAnswer(double a, double b, String c) {double answer = 0;if (c.equals("+")) {answer = a + b;} else if (c.equals("-")) {answer = a - b;} else if (c.equals("*")) {answer = a * b;} else if (c.equals("/")) {answer = a / b;}return answer;}}

雙棧算法代碼如下。

/*** 這是一個全能計算器代碼* 具體思路如下* 1.建立兩個棧,分別是 數字棧 和符號棧* 2.從左到有依次遍歷表達式* 3.如果遇到數字,將數字入數字棧* 4.如果遇到符號,分兩種情況,若符號棧為空,該符號直接入符號棧* 5.若符號棧不為空--繼續判斷該符號的優先級是否小于或等于該棧頂符號優先級,* 如果是,則出棧符號棧頂元素,再出棧兩次數字棧元素,進行運算(最后出棧的數字放前面),運算出來的結果放入數字棧,然后再5操作一次* 如果不是,符號直接入符號棧* 6.最后數字棧剩下最后一個數字,就是結果*/ public class StackCalculator {private Stack<Double> numList;private Stack<String> charList;public StackCalculator() {numList = new Stack<>();charList = new Stack<>();}public Double getPeek(ArrayList<String> cir) {for (int i = 0; i < cir.size(); i++) {String s = cir.get(i);if (s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {if (charList.isEmpty() || comparePriority(s) > comparePriority(charList.peek())) {charList.push(s);} else if (!charList.isEmpty() && comparePriority(s) <= comparePriority(charList.peek())) {while (!charList.isEmpty() && comparePriority(s) <= comparePriority(charList.peek())) {opera();}charList.push(s);}} else {numList.push(Double.parseDouble(s));}}while (numList.size() > 1) {opera();}Double peek = numList.peek();System.out.println(peek + "結果");return peek;}public void opera() {Double second = numList.pop();Double first = numList.pop();String pop = charList.pop();double answer = getSingleAnswer(first, second, pop);numList.push(answer);}public int comparePriority(String opera) {int por = 0;if (opera.equals("+")) {por = 0;}if (opera.equals("-")) {por = 0;}if (opera.equals("*")) {System.out.println("*****");por = 1;}if (opera.equals("/")) {por = 1;}return por;}public double getSingleAnswer(double a, double b, String c) {double answer = 0;if (c.equals("+")) {answer = a + b;} else if (c.equals("-")) {answer = a - b;} else if (c.equals("*")) {answer = a * b;} else if (c.equals("/")) {answer = a / b;}return answer;}}

總結

以上是生活随笔為你收集整理的简单的计算器程序却蕴涵的有趣的数据结构的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。