最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

一、思路分析

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

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

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

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

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

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

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

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

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

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

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

5、最后保留在數(shù)棧中的那個(gè)數(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ù)的問(wèn)題?
? ? ? ? //創(chuàng)建兩個(gè)棧,數(shù)棧,一個(gè)符號(hào)棧
? ? ? ? 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 的每一個(gè)字符
? ? ? ? ? ? ch = expression.substring(index, index+1).charAt(0);
? ? ? ? ? ? //判斷ch是什么,然后做相應(yīng)的處理
? ? ? ? ? ? if(operStack.isOper(ch)) {//如果是運(yùn)算符
? ? ? ? ? ? ? ? //判斷當(dāng)前的符號(hào)棧是否為空
? ? ? ? ? ? ? ? if(!operStack.isEmpty()) {
? ? ? ? ? ? ? ? ? ? //如果符號(hào)棧有操作符,就進(jìn)行比較,如果當(dāng)前的操作符的優(yōu)先級(jí)小于或者等于棧中的操作符,就需要從數(shù)棧中pop出兩個(gè)數(shù),
? ? ? ? ? ? ? ? ? ? //在從符號(hào)棧中pop出一個(gè)符號(hào),進(jìn)行運(yùn)算,將得到結(jié)果,入數(shù)棧,然后將當(dāng)前的操作符入符號(hào)棧
? ? ? ? ? ? ? ? ? ? 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)前的操作符入符號(hào)棧
? ? ? ? ? ? ? ? ? ? ? ? operStack.push(ch);
? ? ? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? ? ? //如果當(dāng)前的操作符的優(yōu)先級(jí)大于棧中的操作符, 就直接入符號(hào)棧.
? ? ? ? ? ? ? ? ? ? ? ? operStack.push(ch);
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? }else {
? ? ? ? ? ? ? ? ? ? //如果為空直接入符號(hào)棧..
? ? ? ? ? ? ? ? ? ? operStack.push(ch); // 1 + 3
? ? ? ? ? ? ? ? }
? ? ? ? ? ? } else { //如果是數(shù),則直接入數(shù)棧

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

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

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

? ? ? ? ? ? ? ? ? ? //判斷下一個(gè)字符是不是數(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ù)棧和符號(hào)棧中pop出相應(yīng)的數(shù)和符號(hào),并運(yùn)行.
? ? ? ? while(true) {
? ? ? ? ? ? //如果符號(hào)棧為空,則計(jì)算到最后的結(jié)果, 數(shù)棧中只有一個(gè)數(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)建一個(gè)棧,直接使用前面創(chuàng)建好
//定義一個(gè) 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];
? ? }

? ? //增加一個(gè)方法,可以返回當(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í),需要從棧頂開始顯示數(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)先級(jí),優(yōu)先級(jí)是程序員來(lái)確定, 優(yōu)先級(jí)使用數(shù)字表示
? ? //數(shù)字越大,則優(yōu)先級(jí)就越高.
? ? public int priority(int oper) {
? ? ? ? if(oper == '*' || oper == '/'){
? ? ? ? ? ? return 1;
? ? ? ? } else if (oper == '+' || oper == '-') {
? ? ? ? ? ? return 0;
? ? ? ? } else {
? ? ? ? ? ? return -1; // 假定目前的表達(dá)式只有 +, - , * , /
? ? ? ? }
? ? }
? ? //判斷是不是一個(gè)運(yùn)算符
? ? public boolean isOper(char val) {
? ? ? ? return val == '+' || val == '-' || val == '*' || val == '/';
? ? }
? ? //計(jì)算方法
? ? public int cal(int num1, int num2, int oper) {
? ? ? ? int res = 0; // res 用于存放計(jì)算的結(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;
? ? }

}

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

相關(guān)文章

  • SpringMVC ViewResolver視圖解析器組件

    SpringMVC ViewResolver視圖解析器組件

    這篇文章主要介紹了SpringMVC ViewResolver視圖解析器組件,Spring MVC的視圖解析器 ViewResolver 是框架中一個(gè)重要的組件,用于將控制器返回的邏輯視圖名稱解析為具體的視圖實(shí)現(xiàn)對(duì)象,最終呈現(xiàn)給用戶的是具體的視圖實(shí)現(xiàn)
    2023-04-04
  • java實(shí)現(xiàn)/創(chuàng)建線程的幾種方式小結(jié)

    java實(shí)現(xiàn)/創(chuàng)建線程的幾種方式小結(jié)

    在JAVA中,用Thread類代表線程,所有線程對(duì)象都必須是Thread類或者Thread類子類的實(shí)例,下面這篇文章主要介紹了java實(shí)現(xiàn)/創(chuàng)建線程的幾種方式,需要的朋友可以參考下
    2021-08-08
  • SpringBoot+WebSocket實(shí)現(xiàn)IM及時(shí)通訊的代碼示例

    SpringBoot+WebSocket實(shí)現(xiàn)IM及時(shí)通訊的代碼示例

    項(xiàng)目中碰到需要及時(shí)通訊的場(chǎng)景,使用springboot集成websocket,即可實(shí)現(xiàn)簡(jiǎn)單的及時(shí)通訊,本文介紹springboot如何集成websocket、IM及時(shí)通訊需要哪些模塊、開發(fā)和部署過(guò)程中遇到的問(wèn)題、以及實(shí)現(xiàn)小型IM及時(shí)通訊的代碼,需要的朋友可以參考下
    2023-10-10
  • springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)

    springboot中mybatis多數(shù)據(jù)源動(dòng)態(tài)切換實(shí)現(xiàn)

    在開發(fā)中,動(dòng)態(tài)數(shù)據(jù)源配置還是用的比較多的,比如在多數(shù)據(jù)源使用方面,又或者是在多個(gè)DB之間切換方面。這里給出一個(gè)動(dòng)態(tài)數(shù)據(jù)源的配置方案,感興趣的可以了解一下
    2021-07-07
  • Java程序設(shè)計(jì)之12個(gè)經(jīng)典樣例

    Java程序設(shè)計(jì)之12個(gè)經(jīng)典樣例

    這篇文章主要給大家分享關(guān)于Java程序設(shè)計(jì)11個(gè)經(jīng)典樣例,主要以舉例的形式詳細(xì)的講解了Java程序設(shè)計(jì)的各種方法,需要的朋友可以參考一下文章具體的內(nèi)容
    2021-10-10
  • 細(xì)說(shuō)Springcloud eureka的幾種主動(dòng)下線服務(wù)的方式

    細(xì)說(shuō)Springcloud eureka的幾種主動(dòng)下線服務(wù)的方式

    這篇文章主要介紹了細(xì)說(shuō)Springcloud eureka的幾種主動(dòng)下線服務(wù)的方式,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Java編程中使用XFire框架調(diào)用WebService程序接口

    Java編程中使用XFire框架調(diào)用WebService程序接口

    這篇文章主要介紹了Java編程中使用XFire調(diào)用WebService程序接口的方法,WebService是一種跨編程語(yǔ)言和跨操作系統(tǒng)平臺(tái)的遠(yuǎn)程調(diào)用技術(shù),需要的朋友可以參考下
    2015-12-12
  • java?System類和Arrays類詳解

    java?System類和Arrays類詳解

    這篇文章主要介紹了java?System類和Arrays類詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-08-08
  • Java格式化輸出詳細(xì)講解(printf、print、println、format等)

    Java格式化輸出詳細(xì)講解(printf、print、println、format等)

    Java的格式化輸出等同于String.Format,與C有很大的相似,下面這篇文章主要給大家介紹了關(guān)于Java格式化輸出(printf、print、println、format等)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2023-03-03
  • Java實(shí)現(xiàn)心跳機(jī)制的方法

    Java實(shí)現(xiàn)心跳機(jī)制的方法

    這篇文章主要介紹了Java實(shí)現(xiàn)心跳機(jī)制的方法,文中講解非常細(xì)致,幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07

最新評(píng)論

松桃| 昔阳县| 大名县| 阿巴嘎旗| 华宁县| 贵溪市| 台北县| 嘉鱼县| 海城市| 洪江市| 武乡县| 上饶县| 剑阁县| 蒲城县| 邮箱| 大同市| 长岭县| 泰宁县| 思南县| 波密县| 交口县| 乳源| 长宁区| 苍南县| 吴桥县| 邮箱| 微山县| 永年县| 靖远县| 吴忠市| 西充县| 蕲春县| 眉山市| 旬邑县| 阜城县| 灌南县| 泗水县| 滕州市| 乌苏市| 高淳县| 区。|