整体界面如下:
这里用到了中缀表达式转后缀表达式,以及计算后缀表达式(也叫逆波兰表达式)。(相关内容可参考数据结构里面的栈)
中缀表达式转后缀表达式:
遍历中缀表达式中的数字和符号:
- 对于数字:直接输出
- 对于符号:
- 左括号:进栈
- 运算符号:与栈顶符号进行优先级比较
- 若栈顶符号优先级低:此符号进栈
- (默认栈顶若是左括号,左括号优先级最低)
- 若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈
- 右括号:将栈顶符号弹出并输出,直到匹配左括号,将左括号和右括号同时舍弃
- 遍历结束:将栈中的所有符号弹出并输出
如 8 +(3 - 1)* 5 => 8 3 1 - 5 * +
step1:将8输出
step2:将“ + ”入栈
step3:将“( ”入栈
step4:将3输出
step5:将“ - ”入栈
step6:将1输出
step7:此时遇到了“ )”,将栈中的“-”出栈输出,舍弃掉左括号与右括号
此时栈中剩下“+”
step8:将“ * ”入栈
step9:将5输出
step10:遍历结束,将栈中的所有符号出栈,即将“ * ”与“ + ”弹出并输出,结束。
计算后缀表达式(也叫逆波兰表达式):
- 遍历后缀表达式中的数字和符号
- 对于数字:进栈
- 对于符号:
- 从栈中弹出右操作数
- 从栈中弹出左操作数
- 根据符号进行运算
- 将运算结果压入栈中
- 遍历结束:栈中的唯一数字为计算结果
还是上面的例子:8 3 1 - 5 * +
step1:将8 , 3 , 1 进栈
step2:遇到“ - ”,将1出栈,作为右操作数,再将3出栈作为左操作数,即3 - 1 ,计算一下,将计算结果2入栈
此时栈中有8 , 2
step3:将5进栈,此时栈中有8 , 2 , 5
step4:遇到了“ * ”,再从栈中弹出两个数,进行 * 运算了,即进行2 * 5运算,将结果10入栈,此时栈中有8 , 10
step5:遇到了“ + ”,从栈中弹出两个数,进行 + 运算了,即进行8 + 10运算,将结果 18入栈,此时栈中只有18
step6:遍历结束,栈中的唯一数字就是计算结果,即此例子结果是18。
下面是具体的实现:
main类:
package examplee;
public class example001 {
public static void main(String args[]) {
new calculator();
}
}
这是计算器的界面以及监听:
package examplee;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class calculator extends JFrame implements ActionListener {
private String b = "";
private String name [] = {"7", "8", "9", "+",
"4", "5", "6", "-",
"1", "2", "3", "*",
".", "0", "=", "/",
"C", "(", ")", "%"};
JFrame f = new JFrame("简单计算器");
Container c = f.getContentPane();//容器
JPanel panel = new JPanel(); //面板
JTextField textfield = new JTextField();//文本框
JButton button[] = new JButton[20];//按钮
calculate cal = new calculate();
Result res = new Result();
public calculator() {
textfield.setHorizontalAlignment(JTextField.RIGHT);//文本框内容右对齐
textfield.setEditable(false);//文本框内容不可编辑
c.add(textfield, BorderLayout.NORTH);
c.add(panel, BorderLayout.CENTER);
panel.setLayout(new GridLayout(5,4));
for(int i=0; i<20; i++) {
button[i] = new JButton(name[i]);
panel.add(button[i]);//将按钮添加到面板上
button[i].addActionListener(this);
}
f.setBounds(500, 200, 280, 400);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public void actionPerformed(ActionEvent e) {
String label = e.getActionCommand();
if(label=="C"||label=="=") {
if(label == "=") {
String s[]=cal.calculate1(this.b);
String result=res.Result1(s);
this.b=result+"";
textfield.setText(this.b);
}
else {
this.b="";
textfield.setText("0");
}
}
else {
this.b=this.b+label;
textfield.setText(this.b);
}
}
}
这是计算后缀表达式的类:
package examplee;
public class Result {
public String Result1(String str[]) {
String Result[] = new String[100];
int top = -1;
for(int i=0; str[i]!=null; i++)
{
if("+-*%/".indexOf(str[i])<0) { //遇到数字字符
top++;
Result[top]=str[i];
}
else if("+-*%/".indexOf(str[i])>=0) //遇到运算符
{
double x,y,n;
x=Double.parseDouble(Result[top]);//出栈一个数字字符,并转换为double类型的数字
top--;
y=Double.parseDouble(Result[top]);//出栈一个数字字符,并转换为double类型的数字
top--;
if ("-".indexOf(str[i])>=0) { //根据运算符进行计算
n=y-x;
top++;
Result[top]=String.valueOf(n);//讲数字转化为String类型,并将运算结果重新入栈
}
if("+".indexOf(str[i])>=0) {
n=y+x;
top++;
Result[top]=String.valueOf(n);
}
if ("*".indexOf(str[i])>=0) {
n=y*x;
top++;
Result[top]=String.valueOf(n);
}
if("/".indexOf(str[i])>=0) {
if(x==0) { //被除数不能为0
String s="ERROR";
return s;
}
else {
n=y/x;
top++;
Result[top]=String.valueOf(n);
}
}
if("%".indexOf(str[i])>=0){
if(x==0){
String s = "ERROR";
return s;
}
else{
n=y%x;
top++;
Result[top]=String.valueOf(n);
}
}
}
}
return Result[top];
}
}
这是中缀表达式转后缀表达式的类:
package examplee;
public class calculate {
public String[] calculate1(String str) {
String s = "";//用来承多位数的字符串
char a[] = new char[100]; //字符型的栈数组
String jieguo[] = new String[100];//存放后缀表达式
int top=-1,j=0;
for(int i=0; i<str.length(); i++)//遍历中缀表达式
{
if("0123456789.".indexOf(str.charAt(i))>=0) //如果存在数字字符
{ //charAt() 方法用于返回指定索引处的字符。索引范围为从 0 到 length()-1
s = "";
for(;i<str.length()&&"0123456789.".indexOf(str.charAt(i))>=0; i++) {
s = s + str.charAt(i);
}
i--;
jieguo[j] = s;
j++;
}
else if("(".indexOf(str.charAt(i))>=0) //遇到左括号
{
top++;
a[top]=str.charAt(i);//左括号入栈
}
else if (")".indexOf(str.charAt(i))>=0)//遇到右括号
{
for (;;)//栈顶元素循环出栈,直到找到左括号为止
{
if (a[top]!='(') { //栈顶元素不是左括号
jieguo[j]=a[top]+"";//栈顶元素出栈
j++;
top--;
}
else { //找到栈顶元素是左括号
top--;//删除栈顶的左括号
break;//循环结束
}
}
}
else if ("*%÷".indexOf(str.charAt(i))>=0)//遇到高优先级运算符
{
if (top==-1)//若栈为空直接入栈
{
top++;
a[top]=str.charAt(i);
}
else//若栈不为空
{
if ("*%÷".indexOf(a[top])>=0)//栈顶元素也为高优先
{
jieguo[j]=a[top]+"";//栈顶元素出栈进入后
j++;
a[top]=str.charAt(i);
}
else if("(".indexOf(a[top])>=0)//栈顶元素为左括号,
{
top++;
a[top]=str.charAt(i);
}
else if("+-".indexOf(a[top])>=0)
{
top++;
a[top]=str.charAt(i);
}
}
}
else if("+-".indexOf(str.charAt(i))>=0)//遇到低优先级运算符
{
if (top==-1)//若栈为空直接入栈
{
top++;
a[top]=str.charAt(i);
}
else//若栈不为空
{
if ("*%÷".indexOf(a[top])>=0)//栈顶元素也为高优先
{
jieguo[j]=a[top]+"";//栈顶元素出栈进入后
j++;
a[top]=str.charAt(i);
}
else if("(".indexOf(a[top])>=0)//栈顶元素为左括号,
{
top++;
a[top]=str.charAt(i);
}
else if("+-".indexOf(a[top])>=0)
{
jieguo[j]=a[top]+"";
top++;
a[top]=str.charAt(i);
}
}
}
}
for(;top!=-1;)//遍历结束后
{
jieguo[j]=a[top]+"";
j++;
top--;
}
return jieguo;
}
}
这只是简单的计算器