利用棧使用簡易計(jì)算器(Java實(shí)現(xiàn))
題目:使用棧計(jì)算類似表達(dá)式:5+2*3-2 的計(jì)算結(jié)果
提示:簡易計(jì)算器操作符號限于+,-,*,/的計(jì)算
分析思路:
1、創(chuàng)建一個數(shù)棧和一個符號棧,數(shù)棧用于存放數(shù)字,符號棧用于存放符號
2、創(chuàng)建一個索引index,用于遍歷表達(dá)式
3、掃描表達(dá)式,如果是數(shù)字直接進(jìn)入數(shù)棧,如果是符號,則需要進(jìn)行判斷。分兩種情況,一是當(dāng)符號棧如果為空,直接將符號入棧。二是不為空,先比較當(dāng)前棧頂?shù)姆柵c將要進(jìn)棧的符號的優(yōu)先級大小,如果將要進(jìn)棧的操作符的優(yōu)先級小,則將數(shù)棧的兩個數(shù)彈出,符號棧的操作符彈出一個,并進(jìn)行計(jì)算,計(jì)算之后的結(jié)果直接進(jìn)入數(shù)棧,如果優(yōu)先級大,就直接進(jìn)棧。
4、掃描完表達(dá)式之后,就順序的從數(shù)棧和符號棧順序的彈出相應(yīng)的數(shù)字和操作符,并進(jìn)行計(jì)算。
5、當(dāng)符號棧為空時,說明已經(jīng)計(jì)算完了,此時留在數(shù)棧的只有一個數(shù)字,就是表達(dá)式計(jì)算之后的結(jié)果。

代碼實(shí)現(xiàn)
package cn.mrlij.stack;
import java.util.Arrays;
import java.util.Scanner;
/**
* 使用數(shù)組實(shí)現(xiàn)棧
*
* @author dreamer
*
*/
public class ArrayStackDemo {
public static void main(String[] args) {
String express = "5011+2*3-2";
int index = 0;//定義一個索引值,用于遍歷表達(dá)式
int num1 = 0;
int num2 = 0;
int res = 0;//計(jì)算結(jié)果
char ch = ' ';
int oper = 0;
String keepNum = "";
ArrayStack numStack = new ArrayStack(10);//創(chuàng)建一個數(shù)棧
ArrayStack operStack = new ArrayStack(10);//創(chuàng)建一個符號棧
while (true){
ch = express.substring(index,index+1).charAt(0);//不停的遍歷操作符
//判斷是否是操作符
if (operStack.isOper(ch)){
//判斷當(dāng)前符號棧是否有符號存在
if(!operStack.isEmpty()){
//不為空則判斷優(yōu)先級
if(operStack.priority(ch)<=operStack.priority(operStack.peek())){
//當(dāng)優(yōu)先級小于棧頂?shù)闹禃r候,彈出兩個數(shù)棧的值進(jìn)行計(jì)算
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = operStack.cal(num1,num2,oper);
//計(jì)算以后將計(jì)算得到的值放入數(shù)棧
numStack.push(res);
//同時將此時的操作符放入符號棧
operStack.push(ch);
}else{
//優(yōu)先級
operStack.push(ch);
}
}else{
//為空直接將符號入棧
operStack.push(ch);
}
}else {
keepNum += ch;
//處理多位數(shù)
if(express.length()-1 == index){
numStack.push(Integer.parseInt(keepNum));
}else {
if(operStack.isOper(express.substring(index+1,index+2).charAt(0))){
numStack.push(Integer.parseInt(keepNum));
keepNum = "";
}
}
// numStack.push(ch-48);
}
index++;
if(index >= express.length()){
break;
}
}
//掃描完之后,將數(shù)棧的值,與操作符中的值進(jìn)行計(jì)算
while (true){
if(operStack.isEmpty()){
break;
}
num1 = numStack.pop();
num2 = numStack.pop();
oper = operStack.pop();
res = operStack.cal(num1,num2,oper);
numStack.push(res);
}
System.out.println("表達(dá)式:"+express+"="+numStack.pop());
}
}
class ArrayStack {
private int MaxSize;// 定義數(shù)組的最大長度
private int[] arr;// 定義數(shù)組,數(shù)據(jù)就放在該數(shù)組
private int top = -1;// 定義棧頂,初始化數(shù)據(jù)為-1
public ArrayStack(int maxSize) {
this.MaxSize = maxSize;
arr = new int[MaxSize];
}
// 判斷數(shù)組是否為空
public boolean isEmpty() {
return top == -1;
}
// 判斷數(shù)組是否滿了
public boolean isFull() {
//System.out.println("棧頂:" + top + "最大長度:" + MaxSize);
return top == MaxSize - 1;
}
//取出棧頂元素
public int peek(){
return arr[top];
}
// 進(jìn)棧
public void push(int val) {
// 先判斷棧是否滿了,滿了就不能添加進(jìn)去
if (isFull()) {
System.out.println("棧已經(jīng)滿了~~");
return;
}
top++;
arr[top] = val;
}
// 出棧
public int pop() {
// 先判斷棧是否為空
if (isEmpty()) {
throw new RuntimeException("棧為空,無法出棧!");
}
int val = arr[top];
top--;
return val;
}
public void show() {
if (isEmpty()) {
System.out.println("沒有數(shù)據(jù)");
return;
}
for (int i = top; i >= 0; i--) {
System.out.print(arr[i] + "\t");
}
System.out.println();
}
/**
* 判斷是否是一個操作符
* @param oper 傳入的字符
* @return 如是操作符返回true,否則返回false
*/
public boolean isOper(char oper){
return oper == '+' || oper == '-' || oper =='*' || oper == '/';
}
/**
* 判斷操作符的優(yōu)先級
* @param oper 傳入的優(yōu)先級
* @return 返回優(yōu)先級 分別是1,-1,0
*/
public int priority(int oper ){
if(oper == '*' || oper == '/'){
return 1;
} else if(oper == '+' || oper == '-'){
return 0;
}else {
return -1;
}
}
//計(jì)算方法
public int cal(int num1,int num2,int oper){
int res = 0;
switch (oper){
case '+': res = num1 + num2;
break;
case '-': res = num2 - num1;
break;
case '*': res = num1 * num2;
break;
case '/': res = num2 /num1;
}
return res;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
利用Spring MVC+Mybatis實(shí)現(xiàn)Mysql分頁數(shù)據(jù)查詢的過程詳解
這篇文章主要給大家介紹了關(guān)于利用Spring MVC+Mybatis實(shí)現(xiàn)Mysql分頁數(shù)據(jù)查詢的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面跟著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-08-08
Java轉(zhuǎn)換解析中間帶有 “T“和“Z“ 的時間格式
這篇文章主要給大家介紹了關(guān)于Java轉(zhuǎn)換解析中間帶有 “T“和“Z“ 的時間格式,相信很多小伙伴在時間格式轉(zhuǎn)換的時候非常頭疼,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-01-01
Java用正則表達(dá)式實(shí)現(xiàn)${name}形式的字符串模板實(shí)例
這篇文章主要給大家介紹了Java如何用正則表達(dá)式實(shí)現(xiàn)${name}形式的字符串模板,文章給出詳細(xì)的實(shí)例代碼,對大家的理解和學(xué)習(xí)會很有幫助,有需要的朋友們下面來一起看看吧。2016-12-12
springboot實(shí)現(xiàn)啟動直接訪問項(xiàng)目地址
這篇文章主要介紹了springboot實(shí)現(xiàn)啟動直接訪問項(xiàng)目地址,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-12-12
SpringBoot集成消息隊(duì)列的項(xiàng)目實(shí)踐
本文主要介紹了SpringBoot集成消息隊(duì)列的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2024-02-02
Java請求轉(zhuǎn)發(fā)和請求重定向區(qū)別詳解
這篇文章主要介紹了Java請求轉(zhuǎn)發(fā)和請求重定向區(qū)別詳解,請求轉(zhuǎn)發(fā)和請求重定向,但二者是完全不同的,所以我們今天就來盤他們的區(qū)別介紹,需要的朋友可以參考一下2022-07-07
idea創(chuàng)建spring?boot項(xiàng)目時javaversion只能選擇17和21解決辦法
這篇文章主要給大家介紹了關(guān)于idea創(chuàng)建spring?boot項(xiàng)目時javaversion只能選擇17和21的解決辦法,文中通過代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下2024-01-01

