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

Java利用棧實(shí)現(xiàn)簡易計算器功能

 更新時間:2022年05月26日 11:50:45   作者:好湯圓  
這篇文章主要為大家詳細(xì)介紹了Java利用棧實(shí)現(xiàn)簡易計算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下

利用棧實(shí)現(xiàn)一個簡易計算器(Java實(shí)現(xiàn)),供大家參考,具體內(nèi)容如下

一、思路分析

當(dāng)我們輸入一個類似于“7*2+100-5+3-4/2”的簡單中綴表達(dá)式時,我們的編譯器能夠利用我們所編寫的代碼將這個表達(dá)式掃描并計算出其結(jié)果

在這個表達(dá)式中主要有兩種元素,一種是數(shù)字,一種是符號,那么我們就需要創(chuàng)建兩個棧結(jié)構(gòu)存儲數(shù)據(jù)

  • 數(shù)棧numStack:存放數(shù)
  • 符號棧operStack:存放運(yùn)算符

1、首先我們需要定義一個index(索引),來遍歷我們的表達(dá)式

2、如果掃描到一個數(shù)字,就直接入數(shù)棧

3、如果掃描到一個運(yùn)算符,那就要分以下幾種情況:

? 3.1、如果當(dāng)前符號棧為空,就直接入棧

? 3.2、如果符號棧有運(yùn)算符,就需要進(jìn)行比較

? 如果當(dāng)前運(yùn)算符的優(yōu)先級小于或等于棧中的運(yùn)算符,就需要從數(shù)棧中pop出兩個數(shù),在符號棧中pop出一個符號,進(jìn)行運(yùn)算,得到結(jié)果,入數(shù)棧,然后將當(dāng)前的操作符入符號棧

? 如果當(dāng)前運(yùn)算符的優(yōu)先級大于棧中的運(yùn)算符,就直接入符號棧

4、當(dāng)表達(dá)式掃描完畢,就順序的從數(shù)棧和符號棧中pop出相應(yīng)的數(shù)和符號,并進(jìn)行計算

5、最后保留在數(shù)棧中的那個數(shù)字就是運(yùn)算的結(jié)果

二、代碼實(shí)現(xiàn)

package com.hsy.stack;

public class Calculator {

? ? public static void main(String[] args) {
? ? ? ? //根據(jù)前面老師思路,完成表達(dá)式的運(yùn)算
? ? ? ? String expression = "7*2+100-5+3-4/2";//如何處理多位數(shù)的問題?
? ? ? ? //創(chuàng)建兩個棧,數(shù)棧,一個符號棧
? ? ? ? ArrayStack2 numStack = new ArrayStack2(10);
? ? ? ? ArrayStack2 operStack = new ArrayStack2(10);
? ? ? ? //定義需要的相關(guān)變量
? ? ? ? int index = 0;//用于掃描
? ? ? ? int num1 = 0;
? ? ? ? int num2 = 0;
? ? ? ? int oper = 0;
? ? ? ? int res = 0;
? ? ? ? char ch = ' '; //將每次掃描得到char保存到ch
? ? ? ? String keepNum = ""; //用于拼接 多位數(shù)
? ? ? ? //開始while循環(huán)的掃描expression
? ? ? ? while(true) {
? ? ? ? ? ? //依次得到expression 的每一個字符
? ? ? ? ? ? ch = expression.substring(index, index+1).charAt(0);
? ? ? ? ? ? //判斷ch是什么,然后做相應(yīng)的處理
? ? ? ? ? ? if(operStack.isOper(ch)) {//如果是運(yùn)算符
? ? ? ? ? ? ? ? //判斷當(dāng)前的符號棧是否為空
? ? ? ? ? ? ? ? if(!operStack.isEmpty()) {
? ? ? ? ? ? ? ? ? ? //如果符號棧有操作符,就進(jìn)行比較,如果當(dāng)前的操作符的優(yōu)先級小于或者等于棧中的操作符,就需要從數(shù)棧中pop出兩個數(shù),
? ? ? ? ? ? ? ? ? ? //在從符號棧中pop出一個符號,進(jìn)行運(yùn)算,將得到結(jié)果,入數(shù)棧,然后將當(dāng)前的操作符入符號棧
? ? ? ? ? ? ? ? ? ? if(operStack.priority(ch) <= operStack.priority(operStack.peek())) {
? ? ? ? ? ? ? ? ? ? ? ? num1 = numStack.pop();
? ? ? ? ? ? ? ? ? ? ? ? num2 = numStack.pop();
? ? ? ? ? ? ? ? ? ? ? ? oper = operStack.pop();
? ? ? ? ? ? ? ? ? ? ? ? res = numStack.cal(num1, num2, oper);
? ? ? ? ? ? ? ? ? ? ? ? //把運(yùn)算的結(jié)果如數(shù)棧
? ? ? ? ? ? ? ? ? ? ? ? numStack.push(res);
? ? ? ? ? ? ? ? ? ? ? ? //然后將當(dāng)前的操作符入符號棧
? ? ? ? ? ? ? ? ? ? ? ? operStack.push(ch);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? //如果當(dāng)前的操作符的優(yōu)先級大于棧中的操作符, 就直接入符號棧.
? ? ? ? ? ? ? ? ? ? ? ? operStack.push(ch);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? //如果為空直接入符號棧..
? ? ? ? ? ? ? ? ? ? operStack.push(ch); // 1 + 3
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else { //如果是數(shù),則直接入數(shù)棧

? ? ? ? ? ? ? ? //numStack.push(ch - 48); //? "1+3" '1' => 1
? ? ? ? ? ? ? ? //分析思路
? ? ? ? ? ? ? ? //1. 當(dāng)處理多位數(shù)時,不能發(fā)現(xiàn)是一個數(shù)就立即入棧,因?yàn)樗赡苁嵌辔粩?shù)
? ? ? ? ? ? ? ? //2. 在處理數(shù),需要向expression的表達(dá)式的index 后再看一位,如果是數(shù)就進(jìn)行掃描,如果是符號才入棧
? ? ? ? ? ? ? ? //3. 因此我們需要定義一個變量 字符串,用于拼接

? ? ? ? ? ? ? ? //處理多位數(shù)
? ? ? ? ? ? ? ? keepNum += ch;

? ? ? ? ? ? ? ? //如果ch已經(jīng)是expression的最后一位,就直接入棧
? ? ? ? ? ? ? ? if (index == expression.length() - 1) {
? ? ? ? ? ? ? ? ? ? numStack.push(Integer.parseInt(keepNum));
? ? ? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? ? ? //判斷下一個字符是不是數(shù)字,如果是數(shù)字,就繼續(xù)掃描,如果是運(yùn)算符,則入棧
? ? ? ? ? ? ? ? ? ? //注意是看后一位,不是index++
? ? ? ? ? ? ? ? ? ? if (operStack.isOper(expression.substring(index+1,index+2).charAt(0))) {
? ? ? ? ? ? ? ? ? ? ? ? //如果后一位是運(yùn)算符,則入棧 keepNum = "1" 或者 "123"
? ? ? ? ? ? ? ? ? ? ? ? numStack.push(Integer.parseInt(keepNum));
? ? ? ? ? ? ? ? ? ? ? ? //重要的!!!!!!, keepNum清空
? ? ? ? ? ? ? ? ? ? ? ? keepNum = "";

? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? ? ? //讓index + 1, 并判斷是否掃描到expression最后.
? ? ? ? ? ? index++;
? ? ? ? ? ? if (index >= expression.length()) {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? }

? ? ? ? //當(dāng)表達(dá)式掃描完畢,就順序的從 數(shù)棧和符號棧中pop出相應(yīng)的數(shù)和符號,并運(yùn)行.
? ? ? ? while(true) {
? ? ? ? ? ? //如果符號棧為空,則計算到最后的結(jié)果, 數(shù)棧中只有一個數(shù)字【結(jié)果】
? ? ? ? ? ? if(operStack.isEmpty()) {
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? }
? ? ? ? ? ? num1 = numStack.pop();
? ? ? ? ? ? num2 = numStack.pop();
? ? ? ? ? ? oper = operStack.pop();
? ? ? ? ? ? res = numStack.cal(num1, num2, oper);
? ? ? ? ? ? numStack.push(res);//入棧
? ? ? ? }
? ? ? ? //將數(shù)棧的最后數(shù),pop出,就是結(jié)果
? ? ? ? int res2 = numStack.pop();
? ? ? ? System.out.printf("表達(dá)式 %s = %d", expression, res2);
? ? }

}

//先創(chuàng)建一個棧,直接使用前面創(chuàng)建好
//定義一個 ArrayStack2 表示棧, 需要擴(kuò)展功能
class ArrayStack2 {
? ? private int maxSize; // 棧的大小
? ? private int[] stack; // 數(shù)組,數(shù)組模擬棧,數(shù)據(jù)就放在該數(shù)組
? ? private int top = -1;// top表示棧頂,初始化為-1

? ? //構(gòu)造器
? ? public ArrayStack2(int maxSize) {
? ? ? ? this.maxSize = maxSize;
? ? ? ? stack = new int[this.maxSize];
? ? }

? ? //增加一個方法,可以返回當(dāng)前棧頂?shù)闹? 但是不是真正的pop
? ? public int peek() {
? ? ? ? return stack[top];
? ? }

? ? //棧滿
? ? public boolean isFull() {
? ? ? ? return top == maxSize - 1;
? ? }
? ? //???
? ? public boolean isEmpty() {
? ? ? ? return top == -1;
? ? }
? ? //入棧-push
? ? public void push(int value) {
? ? ? ? //先判斷棧是否滿
? ? ? ? if(isFull()) {
? ? ? ? ? ? System.out.println("棧滿");
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? top++;
? ? ? ? stack[top] = value;
? ? }
? ? //出棧-pop, 將棧頂?shù)臄?shù)據(jù)返回
? ? public int pop() {
? ? ? ? //先判斷棧是否空
? ? ? ? if(isEmpty()) {
? ? ? ? ? ? //拋出異常
? ? ? ? ? ? throw new RuntimeException("??眨瑳]有數(shù)據(jù)~");
? ? ? ? }
? ? ? ? int value = stack[top];
? ? ? ? top--;
? ? ? ? return value;
? ? }
? ? //顯示棧的情況[遍歷棧], 遍歷時,需要從棧頂開始顯示數(shù)據(jù)
? ? public void list() {
? ? ? ? if(isEmpty()) {
? ? ? ? ? ? System.out.println("???,沒有數(shù)據(jù)~~");
? ? ? ? ? ? return;
? ? ? ? }
? ? ? ? //需要從棧頂開始顯示數(shù)據(jù)
? ? ? ? for(int i = top; i >= 0 ; i--) {
? ? ? ? ? ? System.out.printf("stack[%d]=%d\n", i, stack[i]);
? ? ? ? }
? ? }
? ? //返回運(yùn)算符的優(yōu)先級,優(yōu)先級是程序員來確定, 優(yōu)先級使用數(shù)字表示
? ? //數(shù)字越大,則優(yōu)先級就越高.
? ? public int priority(int oper) {
? ? ? ? if(oper == '*' || oper == '/'){
? ? ? ? ? ? return 1;
? ? ? ? } else if (oper == '+' || oper == '-') {
? ? ? ? ? ? return 0;
? ? ? ? } else {
? ? ? ? ? ? return -1; // 假定目前的表達(dá)式只有 +, - , * , /
? ? ? ? }
? ? }
? ? //判斷是不是一個運(yùn)算符
? ? public boolean isOper(char val) {
? ? ? ? return val == '+' || val == '-' || val == '*' || val == '/';
? ? }
? ? //計算方法
? ? public int cal(int num1, int num2, int oper) {
? ? ? ? int res = 0; // res 用于存放計算的結(jié)果
? ? ? ? switch (oper) {
? ? ? ? ? ? case '+':
? ? ? ? ? ? ? ? res = num1 + num2;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case '-':
? ? ? ? ? ? ? ? res = num2 - num1;// 注意順序
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case '*':
? ? ? ? ? ? ? ? res = num1 * num2;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? case '/':
? ? ? ? ? ? ? ? res = num2 / num1;
? ? ? ? ? ? ? ? break;
? ? ? ? ? ? default:
? ? ? ? ? ? ? ? break;
? ? ? ? }
? ? ? ? return res;
? ? }

}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • SpringBoot?實(shí)現(xiàn)動態(tài)添加定時任務(wù)功能

    SpringBoot?實(shí)現(xiàn)動態(tài)添加定時任務(wù)功能

    這篇文章主要介紹了SpringBoot?動態(tài)添加定時任務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-02-02
  • Mybatis-Plus同時使用邏輯刪除和唯一索引的問題及解決辦法(報數(shù)據(jù)重復(fù)Duplicate entry的問題)

    Mybatis-Plus同時使用邏輯刪除和唯一索引的問題及解決辦法(報數(shù)據(jù)重復(fù)Duplicate entry的

    在開發(fā)中,我們經(jīng)常會有邏輯刪除和唯一索引同時使用的情況,但當(dāng)使用mybatis plus時,如果同時使用邏輯刪除和唯一索引,會報數(shù)據(jù)重復(fù)Duplicate entry的問題,如何解決這個問題呢,小編給大家分享Mybatis-Plus同時使用邏輯刪除和唯一索引的問題及解決辦法,一起看看吧
    2023-11-11
  • Java 添加超鏈接到 Word 文檔方法詳解

    Java 添加超鏈接到 Word 文檔方法詳解

    這篇文章主要介紹了Java 添加超鏈接到 Word 文檔方法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot如何手寫一個starter并使用這個starter詳解

    SpringBoot如何手寫一個starter并使用這個starter詳解

    starter是SpringBoot中的一個新發(fā)明,它有效的降低了項(xiàng)目開發(fā)過程的復(fù)雜程度,對于簡化開發(fā)操作有著非常好的效果,下面這篇文章主要給大家介紹了關(guān)于SpringBoot如何手寫一個starter并使用這個starter的相關(guān)資料,需要的朋友可以參考下
    2022-12-12
  • Java實(shí)現(xiàn)文件上傳的方法

    Java實(shí)現(xiàn)文件上傳的方法

    這篇文章主要為大家詳細(xì)介紹了Java實(shí)現(xiàn)文件上傳的方法,供大家參考,感興趣的朋友可以參考一下
    2016-05-05
  • JavaWeb中的文件的上傳和下載

    JavaWeb中的文件的上傳和下載

    JavaWeb 文件的上傳和下載是指在Web應(yīng)用中實(shí)現(xiàn)用戶上傳文件到服務(wù)器和從服務(wù)器下載文件的功能,通過JavaWeb技術(shù),可以方便地實(shí)現(xiàn)文件的上傳和下載操作,提供更好的用戶體驗(yàn)和數(shù)據(jù)交互,需要的朋友可以參考下
    2023-10-10
  • windows環(huán)境下java開發(fā)工具maven的安裝教程圖解

    windows環(huán)境下java開發(fā)工具maven的安裝教程圖解

    Maven是一個項(xiàng)目管理和綜合工具。Maven提供了開發(fā)人員構(gòu)建一個完整的生命周期框架。這篇文章主要介紹了windows環(huán)境下java開發(fā)工具maven的安裝,非常不錯對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07
  • SpringBoot如何使用p6spy監(jiān)控數(shù)據(jù)庫

    SpringBoot如何使用p6spy監(jiān)控數(shù)據(jù)庫

    這篇文章主要介紹了SpringBoot如何使用p6spy監(jiān)控數(shù)據(jù)庫問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-01-01
  • Java使用PreparedStatement接口及ResultSet結(jié)果集的方法示例

    Java使用PreparedStatement接口及ResultSet結(jié)果集的方法示例

    這篇文章主要介紹了Java使用PreparedStatement接口及ResultSet結(jié)果集的方法,結(jié)合實(shí)例形式分析了PreparedStatement接口及ResultSet結(jié)果集的相關(guān)使用方法與操作注意事項(xiàng),需要的朋友可以參考下
    2018-07-07
  • Java Map.get()返回指定鍵所映射的值

    Java Map.get()返回指定鍵所映射的值

    這篇文章主要介紹了Java Map.get()返回指定鍵所映射的值,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評論