中缀表达式计算器——Java实现,有简单图形界面

更新时间:2023-07-04 14:39:53 阅读: 评论:0

中缀表达式计算器——Java实现,有简单图形界⾯
中缀表达式计算器——Java实现,有简单图形界⾯
前⾔:
本篇⽂章撰写的初衷是为了记录本⼈的学习以及便于本⼈的再次学习,并为感兴趣的读者提供⼀个简单的思路参考。由于本⼈的能⼒有限,所以出现错误之处尽请见谅,如若能指出错误之处,笔者不胜感激。
问题描述:
给定⼀个中缀表达式,将中缀表达式转换为后缀表达式(逆波兰表达式),并计算出逆波兰表达式的值。
本逆波兰计算器限制:
1. ⽀持多位整数,不⽀持⼩数(对于⽀持⼩数的代码编写有兴趣的读者可以⾃⾏思考)
2. ⽀持操作符: ‘+’, ‘-’, ‘*’, ‘/’, ‘(’, ‘)’
喜形于色
逆波兰计算器算法:
⼀、中缀表达式转换为后缀表达式(逆波兰表达式)算法:
1. 初始化两个栈,⼀个为存储操作符的操作符栈,⼀个为存储逆波兰表达式的逆波兰表达式栈。
2. 从左⾄右扫描中缀表达式。
3. 若读取到的字符为数字,则向后分析直到数字串的结束,并将数字串压⼊逆波兰表达式栈。
4. 若读取到的字符为’(’,则直接将’(‘压⼊操作符栈,该操作符只有遇到右括号’)'的时候出栈。
5. 若读取到的字符为’)’,则将操作符栈中的栈顶操作符依次出栈并压⼊逆波兰表达式栈,直到遇到左括号’(‘为⽌,将操作符栈中栈顶的左括
号’('出栈。
6. 若读取到的字符为运算符’+’, ‘-’, ‘*’, ‘/’:
a. 如果操作符栈为空或栈顶元素为’(’,则将读取到运算符直接压⼊操作符栈;
b. 如果读取的运算符的优先级⾼于操作符栈栈顶运算符的优先级,则将读取的运算符直接压⼊操作符栈;
c. 如果读取的运算符的优先级低于或等于操作符栈栈顶运算符的优先级,则将操作符栈栈顶运算符出栈并压⼊逆波兰表达式栈,将读取到的运算符
压⼊操作符栈。(注意,此处优先级的⽐较是不断⽐较操作符栈栈顶运算符的优先级直到读取到的运算符的优先级⾼于操作符栈栈顶运算符的优先级或遇到’('或栈空)。
7. 重复2-6操作直到输⼊的中缀表达式扫描完毕,若操作符栈中仍然存在运算符,则将操作符栈中栈顶的运算符依次出栈并压⼊逆波兰表达式栈直到
操作符栈为空。
8. 逆波兰表达式栈的出栈元素的逆序为中缀表达式转换后的后缀表达式(逆波兰表达式)。
⼆、后缀表达式(逆波兰表达式)求值算法:
1. 初始化⼀个操作数栈。
2. 从左⾄右依次扫描后缀表达式的单元。
3. 如果扫描的单元是数字串,则将其转换为数字,并压⼊操作数栈,并扫描下⼀个单元。
4. 如果扫描的单元是运算符,则对操作数栈栈顶上的两个操作数执⾏该运算(取两次栈顶),并将运算结果重新压⼊操作数栈。
5. 重复2-4操作,直到后缀表达式单元扫描完毕,最终操作数栈中栈顶元素即为计算结果值。
测试举例:
输⼊中缀表达式:10+((20+30)*40)-50 (注意输⼊为英⽂字符)
求得后缀表达式:10 20 30 + 40 * + 50 - (中间⽤空格隔开)
后缀表达式计算结果:1960
中缀表达式转后缀表达式过程分析:
扫描到的
字符操作符栈
(栈底->栈
顶)经典电影
逆波兰表达式栈(栈
底->栈顶)
说明
1扫描到为数字,向后扫描直到数字串的结尾
010扫描到为数字串结尾,数字串压⼊逆波兰表达式栈
++10操作符栈为空,运算符直接压⼊操作符栈
(+,(10扫描到左括号’(’,直接压⼊操作符栈
(+,(,(10扫描到左括号’(’,直接压⼊操作符栈
2+,(,(10扫描到为数字,向后扫描直到数字串的结尾
0+,(,(10,20扫描到为数字串结尾,数字串压⼊逆波兰表达式栈
++,(,(,+10,20操作符栈栈顶为左括号’(’,运算符直接压⼊操作符栈
3+,(,(,+10,20扫描到为数字,向后扫描直到数字串的结尾
0+,(,(,+10,20,30扫描到为数字串结尾,数字串压⼊逆波兰表达式栈
)+,(10,20,30,+扫描到右括号’)’,弹出操作符栈栈顶运算符并压⼊逆波兰表达式栈直⾄遇到左括号,左括号出栈*+,(,*10,20,30,+操作符栈栈顶为左括号’(’,运算符直接压⼊操作符栈
4+,(,*10,20,30,+扫描到为数字,向后扫描直到数字串的结尾
0+,(,*10,20,30,+,40扫描到为数字串结尾,数字串压⼊逆波兰表达式栈
)+10,20,30,+,40,*扫描到右括号’)’,弹出操作符栈栈顶运算符并压⼊逆波兰表达式栈直⾄遇到左括号,左括号出栈
--10,20,30,+,40,*,+扫描到的’-‘运算符与运算符栈的栈顶运算符’+‘优先级相同,故将栈顶运算符出栈并压⼊逆波兰表达式栈中,因为此时操作符栈已为空,故直接将扫描到的’-'压⼊操作符栈
5-10,20,30,+,40,*,+扫描到为数字,向后扫描直到数字串的结尾
0-10,20,30,+,40,*,+,50扫描到为数字串结尾,数字串压⼊逆波兰表达式栈
中缀表达
式扫描完
10,20,30,+,40,*,+,50,-将操作符栈中的运算符弹出并压⼊逆波兰表达式栈后缀表达式的计算分析过程:
扫描到的单元操作数栈(栈底->
栈顶)
说明
1010扫描到的单元是数字串,则将其转换为数字,并压⼊操作数栈2010,20扫描到的单元是数字串,则将其转换为数字,并压⼊操作数栈3010,20,30扫描到的单元是数字串,则将其转换为数字,并压⼊操作数栈
+10,50扫描到的单元是运算符,则对操作数栈栈顶上的两个操作数执⾏该运算(取两次栈顶)20+30,并 将运算结果50
重新压⼊操作数栈。
4010,50,40扫描到的单元是数字串,则将其转换为数字,并压⼊操作数栈
*10,2000扫描到的单元是运算符,则对操作数栈栈顶上的两个操作数执⾏该运算(取两次栈顶)50*40,并 将运算结果
2000重新压⼊操作数栈。
+2010扫描到的单元是运算符,则对操作数栈栈顶上的两个操作数执⾏该运算(取两次栈顶)10+2000,并 将运算结果
2010重新压⼊操作数栈。
502010,50扫描到的单元是数字串,则将其转换为数字,并压⼊操作数栈
扫描到的单元是运算符,则对操作数栈栈顶上的两个操作数执⾏该运算(取两次栈顶)2010-50,并 将运算结果
-19601960重新压⼊操作数栈。
后缀表达式扫描
完毕1960后缀表达式单元扫描完毕,最终操作数栈中栈顶元素即为计算结果值
扫描到的单元操作数栈(栈底->
野餐作文栈顶)
说明
代码运⾏截图:
Java源代码:
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
/**
* 逆波兰式计算器
*
* @author 独孤猿1998
*
*/
public class InverPolishCalculator extends JFrame {
车全险private static final long rialVersionUID =1L;
private JPanel backgroundPanel;
private JLabel nifixExpressionLabel;
private JTextField nifixExpressionTextField;
private JButton calculateButton;
private JButton clearButton;
private JLabel postfixExpressionLabel;
private JTextField postfixExpressionTextField;
private JLabel calculateResultLabel;
private JTextField calculateResultTextField;
private static Font textFont =new Font("微软雅⿊", Font.PLAIN,18); private static Font buttonFont =new Font("微软雅⿊", Font.PLAIN,16); public InverPolishCalculator(){
initialization();
}
/**
* 窗⼝初始化的⽅法
*/
public void initialization(){
this.tTitle("逆波兰计算器");//设置窗⼝标题
this.tSize(550,320);//设置窗⼝⼤⼩
this.tSize(550,320);//设置窗⼝⼤⼩
this.tLocationRelativeTo(null);//设置窗⼝居中
this.tResizable(fal);//设置窗⼝⼤⼩不可改变
this.tDefaultCloOperation(EXIT_ON_CLOSE);
addViewElement();//窗⼝添加组件
this.tVisible(true);
}
/**
* 窗⼝添加组件的⽅法
*/
public void addViewElement(){
backgroundPanel =new JPanel(null);
nifixExpressionLabel =new JLabel("请输⼊中缀表达式:");
nifixExpressionLabel.tSize(300,20);
nifixExpressionLabel.tLocation(40,50);
nifixExpressionLabel.tFont(textFont);
backgroundPanel.add(nifixExpressionLabel);
nifixExpressionTextField =new JTextField();
nifixExpressionTextField.tSize(300,30);
nifixExpressionTextField.tLocation(40,75);
nifixExpressionTextField.tFont(textFont);
backgroundPanel.add(nifixExpressionTextField);
calculateButton =new JButton("计算");
calculateButton.tSize(70,30);
calculateButton.tLocation(350,75);
calculateButton.tFont(buttonFont);
calculateButton.ateRaidBevelBorder());
calculateButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
postfixExpressionTextField.tText(Text()));
calculateResultTextField.tText(""+Text())); }
});
backgroundPanel.add(calculateButton);
clearButton =new JButton("清空");
clearButton.tSize(70,30);
clearButton.tLocation(430,75);
clearButton.tFont(buttonFont);
clearButton.ateRaidBevelBorder());
clearButton.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
nifixExpressionTextField.tText("");
postfixExpressionTextField.tText("");
calculateResultTextField.tText("");
}
});
backgroundPanel.add(clearButton);
postfixExpressionLabel =new JLabel("中缀表达式转换后的后缀表达式:");
postfixExpressionLabel.tSize(300,20);
postfixExpressionLabel.tLocation(40,115);
postfixExpressionLabel.tFont(textFont);
医保卡换新卡流程
backgroundPanel.add(postfixExpressionLabel);
postfixExpressionTextField =new JTextField();
postfixExpressionTextField.tSize(300,30);
postfixExpressionTextField.tLocation(40,140);
postfixExpressionTextField.tLocation(40,140);
postfixExpressionTextField.tFont(textFont);
backgroundPanel.add(postfixExpressionTextField);
calculateResultLabel =new JLabel("计算结果:");
外成语calculateResultLabel.tSize(300,20);
calculateResultLabel.tLocation(40,180);
calculateResultLabel.tFont(textFont);
backgroundPanel.add(calculateResultLabel);
calculateResultTextField =new JTextField();
calculateResultTextField.tSize(300,30);
calculateResultTextField.tLocation(40,205);
calculateResultTextField.tFont(textFont);
backgroundPanel.add(calculateResultTextField);
this.tContentPane(backgroundPanel);
}
/**
* 中缀表达式转换为后缀表达式的⽅法
* @param nifixExpression 中缀表达式
* @return 后缀表达式(逆波兰表达式)
*/
public static String nifixTransformPostfix(String nifixExpression){
Stack<Character> operatorStack =new Stack<Character>();//初始化存储操作符的操作符栈
Stack<String> postfixExpressionStack =new Stack<String>();//初始化存储逆波兰表达式的逆波兰表达式栈
int length = nifixExpression.length();//中缀表达式的字符串长度
int index =0;//⽤于指向扫描到中缀表达式的位置
char element =' ';//保存当前扫描到中缀表达式的字符
String number = null;//⽤于存储多位数字
while(index < length){//从左⾄右扫描中缀表达式
number ="";绩效激励
element = nifixExpression.charAt(index);
if(element >='0'&& element <='9'){//若读取到的字符为数字
while(element >='0'&& element <='9'){//则向后分析直到数字串的结束
number = number + element;
index++;
if(index == length){
break;
}
element = nifixExpression.charAt(index);
}
文艺名
postfixExpressionStack.push(number);//并将数字串压⼊逆波兰表达式栈
continue;
}el if(element =='('){//若读取到的字符为'('
operatorStack.push(element);//则直接将'('压⼊操作符栈
}el if(element ==')'){//若读取到的字符为')'
while(operatorStack.peek()!='('){//则将操作符栈中的栈顶操作符依次出栈并压⼊逆波兰表达式栈,直到遇到左括号'('为⽌
postfixExpressionStack.push(operatorStack.pop().toString());
}
operatorStack.pop();//将操作符栈中栈顶的左括号'('出栈
}el if(element =='+'|| element =='-'|| element =='*'|| element =='/'){//若读取到的字符为运算符'+', '-', '*', '/'
if(operatorStack.isEmpty()|| operatorStack.peek()=='('){//如果操作符栈为空或栈顶元素为'('
operatorStack.push(element);//则将读取到运算符直接压⼊操作符栈
}el OperatorPriority(element)> OperatorPriority(operatorStack.peek())){//如果读取的运算符的优先级⾼于操作符栈栈顶运算符的优先级
operatorStack.push(element);//则将读取的运算符直接压⼊操作符栈
}el{//如果读取的运算符的优先级低于或等于操作符栈栈顶运算符的优先级
//则将操作符栈栈顶运算符出栈并压⼊逆波兰表达式栈(注意,此处优先级的⽐较是不断⽐较操作符栈栈顶运算符的优先级直到读取到的运算符的优先级⾼于操作符栈栈顶运算符的优先级或遇到'('或栈空)
while(!operatorStack.isEmpty()&& operatorStack.peek()!='('&& OperatorPriority(element)<= OperatorPriority(operatorStack. peek())){
postfixExpressionStack.push(operatorStack.pop().toString());
}
operatorStack.push(element);//将读取到的运算符压⼊操作符栈。
}

本文发布于:2023-07-04 14:39:53,感谢您对本站的认可!

本文链接:https://www.wtabcd.cn/fanwen/fan/82/1078078.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:表达式   运算符   扫描
相关文章
留言与评论(共有 0 条评论)
   
验证码:
推荐文章
排行榜
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图