Java项目1:计算器(Awt + Swing)
目录
- 1. 项目介绍
- 1.1 计算器预期功能介绍
- 1.2 开发环境介绍
- 2. 项目规划
- 2.1 设计项目程序框图
- 2.2 规划计算器样式图
- 3. 具体实现
- 3.1 准备资源
- 3.2 界面设计,排版组件
- 3.3 设置按钮监听事件,实现计算器所有功能
- 3.3.1 实现点击按钮 显示数字功能
- 3.3.2 定义运算类 简单实现加减乘除
- 3.3.3 退格功能的实现
- 3.3.4 定义进制转换类
- 3.3.4.1 十进制转化为其他进制
- 3.3.4.2 其他进制转化为十进制
- 3.3.4.3 其他进制转化为二进制
- 3.3.4 完善其他计算功能
- 3.3.4.1 实现求n次方,开n次方
- 3.3.4.2 实现求方差、求标准差
- 3.3.4.3 实现取模计算
- 3.3.4.4 实现记录功能
- 3.3.4.4 实现撤回功能
- 3.3.5 实现字体自动缩小功能
- 3.4 调整计算器整体界面
- 3.5 修改程序图标
- 4. 项目总结
- 4.1 项目实现的功能以及作用
- 4.2 项目存在的缺陷
- 4.3 心得体会
- 最终代码
1. 项目介绍
1.1 计算器预期功能介绍
在计算方面,有加减乘除、取模、开n次方、开根号、进制转换、求平均值、求标准差功能。
在互动方面,有求值、撤回、退格、清零功能。
1.2 开发环境介绍
开发软件:intelliJ IDEA 2020.1 版本
环境变量:JDK 14
2. 项目规划
2.1 设计项目程序框图
下图采用wps软件设计,简易计算器程序框图

2.2 规划计算器样式图
大概就以下图为标准,在设计阶段会根据实际情况作小幅度调整

3. 具体实现
3.1 准备资源
准备一张简单的宣传图 这里我选择的大小是600 * 100

3.2 界面设计,排版组件
import javax.swing.*;
import java.awt.*;
import java.net.URL;class main {public static void main(String[] args) {JFrame frame = new CalJFrame("简 易 计 算 器");}
}class CalJFrame extends JFrame{//定义3个面板 以及 一个图片JPanel Picture = new JPanel(new BorderLayout());JPanel Result = new JPanel(new GridLayout(1,1));JPanel Cal = new JPanel(new GridLayout(6,5));JLabel head = new JLabel();//定义初始化面板函数public void iniPanel(){//固定画板的大小Cal.setPreferredSize(new Dimension(400,440));Result.setPreferredSize(new Dimension(580, 80));head.setPreferredSize(new Dimension(600, 100));this.setBounds(1,1,600,700);}//定义设置面板函数public void SetPanel(){//设置面板1 ----> 操作的按键面String []title = {"(",")","退格","清零","撤回","7","8","9","/",",","4","5","6","X","求平均值","1","2","3","—","求方差","0",".","=","+","求标准差","10转n","n转2","%","求n次方","开n次方"};//列举按钮标题for(String temp : title){JButton newButton = new JButton(temp);//设置按钮字体格式newButton.setFont(new Font("黑体",Font.PLAIN,20));Cal.add(newButton);}//设置面板2 ----> 顶部的图片head.setIcon(new ImageIcon("src/pic.jpg"));Picture.add(head);//设置面板3 ----> 结果显示界面Result.setLayout(new GridLayout(3,1));JTextField result1 = new JTextField("");JTextField result2 = new JTextField("");JTextField result3 = new JTextField("0");//设置文本框字体格式Font x = new Font("Serif",0,30);result1.setFont(x);result2.setFont(x);result3.setFont(x);result1.setBackground(Color.WHITE);result2.setBackground(Color.WHITE);result3.setBackground(Color.WHITE);result1.setEditable(false);result2.setEditable(false);result3.setEditable(false);//设置文本框对其方式为--> 右对齐result1.setHorizontalAlignment(JTextField.RIGHT);result2.setHorizontalAlignment(JTextField.RIGHT);result3.setHorizontalAlignment(JTextField.RIGHT);Result.add(result1);Result.add(result2);Result.add(result3);}public CalJFrame(String s){this.setTitle(s);Container container = this.getContentPane();iniPanel(); //初始化面板SetPanel(); //设置面板//添加面板进入窗口容器container.add(Picture,BorderLayout.NORTH);container.add(Result,BorderLayout.CENTER);container.add(Cal,BorderLayout.SOUTH);this.setVisible(true);}
}
效果图

3.3 设置按钮监听事件,实现计算器所有功能
3.3.1 实现点击按钮 显示数字功能
在设置按钮标题处,添加监听事件
ButtonMonitor1 keyMonitor = new ButtonMonitor1();for(String temp : title){JButton newButton = new JButton(temp);//设置按钮字体格式newButton.setFont(new Font("黑体",Font.PLAIN,20));newButton.setActionCommand(temp); //设置命令为按钮标题newButton.addActionListener(keyMonitor);//添加监听事件Cal.add(newButton);}
同时定义一个监听类用于处理按钮监听
class ButtonMonitor1 implements ActionListener{@Overridepublic void actionPerformed(ActionEvent e){String command = e.getActionCommand(); //读取按钮内容/* 单个标题的 按钮处理*/if(command.length() == 1){if(command.charAt(0) >='0' && command.charAt(0) <='9')if(result3.getText().equals("0") ) result3.setText(command);else result3.setText(result3.getText() + command);}/* 其他标题 按钮处理*/if(command.equals("清零")) result3.setText("0");}}
效果图

3.3.2 定义运算类 简单实现加减乘除
采用中缀表达式求值方法:
定义两个栈,运算数栈 O p e r a n d Operand Operand, 运算符栈 O p e r a t o r Operator Operator
运算思路:
一、定义 C a l O n c e CalOnce CalOnce 函数:
O p e r a t o r Operator Operator 出栈 1 1 1次 ,记为 c m d cmd cmd。
O p e r a n d Operand Operand 出栈 2 2 2次,分别记为 b , a b, a b,a 。
O p e r a n d Operand Operand 入栈 a a a c m d cmd cmd b b b 的结果。
二、优先级概念(记为priority 缩写p):
- p ( + , − ) p(+,-) p(+,−) < = <= <= p ( + , − , ∗ , / ) p(+,-,*,/) p(+,−,∗,/)
- p ( ∗ , / ) p(*,/) p(∗,/) > = >= >= p ( + , − , ∗ , / ) p(+,-,*,/) p(+,−,∗,/)
- p ( ( , ) ) p((,)) p((,)) > > > p ( + , − , ∗ , / ) p(+,-,*, /) p(+,−,∗,/)
三、遍历文本框中的式子,设当前字符为 C C C,栈顶字符为 T T T
- C C C为数字,用一维数组存单个数字, C C C后移,重复操作直到 C C C不是数字为止,若位数 i i i 不为 0 0 0 则将一维数组里的每一位数转化为一个数字。并将数字入栈,继续下述操作。
- O p e r a t o r Operator Operator为空 o r or or T T T 为左括号, o r or or p ( C ) > = p ( T ) p(C) >= p(T) p(C)>=p(T) 时,将 C C C直接入栈, 跳转 step 1。
- C C C 是右括号时, C a l O n c e CalOnce CalOnce直至遇到下一个左括号,跳转step 1。
- p ( C ) < p ( T ) p(C) < p(T) p(C)<p(T) 时, C a l O n c e CalOnce CalOnce 直到栈空 o r or or p ( C ) < p ( T ) p(C) < p(T) p(C)<p(T),跳转 s t e p 1 step1 step1。
计算类 Code
class Calculate {public Stack <Integer> Operand = new Stack<Integer>(); //运算数栈public Stack <Character> Operator= new Stack<Character>(); //运算符栈public int Result(String s){char []c = s.toCharArray();int i = 0; //用于计数 , 存多位数的位数大小int []a = new int[30]; //存多位数的每一位//遍历计算式子for(int k = 0; k < c.length; k++){/* 先读取数字 */while(c[k] >= '0' && c[k] <= '9'){a[i++] = c[k] - '0';k++;if(k == c.length) break; // 特判最后一位数}if(i!=0){int num = 0;for(int j = 0; j < i; j++){num += a[j] * Math.pow(10, i - j - 1);a[j] = 0;}Operand.push(num); //读取多位数 入栈i = 0;if(k == c.length) break;}// Step 1: 考虑特殊情况: 空栈, 栈顶为左括号,或者 当前级数更大 直接入栈if(Operator.empty() || Operator.peek() == '(' || c[k] == '*' || c[k] =='/' || c[k] == '(') Operator.push(c[k]);/* Step 2: 遇到右括号 需要一直计算到下一个左括号为 止 */else if(c[k] == ')') {while (!Operator.empty() && Operator.peek() != '(') {CalOnce();}if(Operator.pop() != '(') state = 2; // 不存在左括号 则是错误式子}/* Step 3: 一般情况 */else {while(!Operator.empty() && IsSmall(c[k], Operator.peek())) {CalOnce();}Operator.push(c[k]);}}CalOnce(); /* 防止遗漏 */return Operand.peek();}public int CalOnce(){if(Operator.empty()) return -1; //不存在运算符则返回-1Character cmd = Operator.pop(); //读取运算符int b = Operand.pop();int a = Operand.pop();int c = 0;switch(cmd){case '+': c = a + b;break;case '-': c = a - b;break;case '*': c = a * b;break;case '/': c = a / b;break;default:break;}Operand.push(c);return c;}/* 用于判断 两运算符大小 */public boolean IsSmall(Character a, Character b){if(a == '+' || a == '-')return true;if(a == '*' || a == '/')return b == '*' || b =='/';return false;}}
监听类的更新,实现基础运算功能
class ButtonMonitor1 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {String command = e.getActionCommand(); //读取按钮内容if(state == 0){result3.setText("");state = 1;}/* 单个按钮标题的 按钮处理*/if (command.length() == 1) {/* case 1: 处理按钮为数字 或者 运算符 */char cmd = command.charAt(0);if (cmd >= '0' && cmd <= '9' || cmd == '+' || cmd == '-' || cmd =='*' || cmd =='/' || cmd =='(' || cmd == ')') {result3.setText(result3.getText() + command);}/* case 2: 计算结果 */if(cmd == '='){result3.setText(Integer.toString(calculate.Result(result3.getText())));state = 1;}}/* 清零按钮处理*/if (command.equals("清零")) {result3.setText("0");state = 0;calculate.Operator.clear();calculate.Operand.clear();}}}
效果图

3.3.3 退格功能的实现
if(command.equals("退格")){String s = result3.getText();if(s.length() >= 1) s = s.substring(0, s.length()-1);result3.setText(s);
}
效果图

3.3.4 定义进制转换类
3.3.4.1 十进制转化为其他进制
public String TenToN(String num, String n){int []a = new int[100];char []s = num.toCharArray();int nn = Integer.parseInt(n);//将字符数组转化成数字int i = 0, sum = 0;for(int k = s.length - 1; k >= 0; k--){sum += (s[k] - '0') * Math.pow(10,i);i++;}i = 0;while(sum!=0){a[i++] = sum % nn;sum /= nn;}StringBuffer ss = new StringBuffer();while(i > 0){i--;if(a[i] <= 9) ss.append(a[i]);else {int b = a[i] - 10 + 65;ss.append((char)b);}}return "计算结果是:" + ss.toString();}
效果图

3.3.4.2 其他进制转化为十进制
public String NToTen(String num, String n){int []a = new int[100];char []s = num.toCharArray();int nn = Integer.parseInt(n);//将字符数组转化成数字int i = 0, sum = 0;for(int k = s.length - 1; k >= 0; k--){if(s[k] >= 'A' && s[k] <= 'Z'){int b = s[k] - 65;sum += b * Math.pow(nn, i);}else sum += (s[k] - '0') * Math.pow(nn,i);i++;}return String.valueOf(sum);}
效果图

3.3.4.3 其他进制转化为二进制
public String NToTwo(String num, String n){return TenToN(NToTen(num, n), "2");}
效果图

3.3.4 完善其他计算功能
3.3.4.1 实现求n次方,开n次方
public String Powx(String num, String n){int a = Integer.parseInt(num);int x = Integer.parseInt(n);return "计算结果是" + String.valueOf(Math.pow(a,x));}public String SqrtPlus(String num, String n){int a = Integer.parseInt(num);int x = Integer.parseInt(n);return "计算结果是" + String.valueOf(Math.pow(a,1.0 / x));}
3.3.4.2 实现求方差、求标准差
/* 求平均值方法*/public String Average(String num) {String[] strnum = num.split(","); // 字符串分割Double res = 0.0;for (int i = 0; i < strnum.length; ++i)res += Double.valueOf(strnum[i]);return String.valueOf(res / strnum.length);}/* 求标准差方法 */public String Standard(String num){String[] strnum = num.split(",");Double ave = Double.valueOf(Average(num));Double ans = 0.0;for (int i = 0; i < strnum.length; ++i)ans += Math.pow(Double.valueOf(strnum[i]) - ave , 2);return String.valueOf(Math.sqrt(ans / strnum.length));}
3.3.4.3 实现取模计算
public String modd(String num){String[] strnum = num.split("%");int a = Integer.valueOf(strnum[0]);int b = Integer.valueOf(strnum[1]);return a + "%" + b + "=" + String.valueOf(a % b);}
3.3.4.4 实现记录功能
更改求值按钮 和 记录按钮的监听事件
boolean Record = false; //记录模式的开关class ButtonMonitor1 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {String command = e.getActionCommand();if(command.equals("记录")){if(!result1.getText().equals("记录模式开启")) {result1.setText("记录模式开启");Record = true;result2.setEditable(false);}else {result1.setText("记录模式关闭");Record = false;}result2.setText("");}if(command.equals("=")){String res = Integer.toString(calculate.Result(result3.getText()));result3.setText(res);if(Record == true){result2.setText(result2.getText() + res + ",");}state = 1; //0表示未计算,1表示计算中 2表示错误}
}
效果图

3.3.4.4 实现撤回功能
if(command.equals("撤回")){if(ress.empty()) {result3.setText("0"); state = 0;}else result3.setText(ress.pop());
}
if(command.equals("=")){String res = Integer.toString(calculate.Result(result3.getText()));result3.setText(res);if(Record == true){result2.setText(result2.getText() + res + ",");
}ress.push(res);state = 1;
}
效果图

3.3.5 实现字体自动缩小功能
public void Define(){if(result3.getText().length() >= 43) result3.setFont(new Font("黑体", Font.PLAIN, 18));else if(result3.getText().length() >= 31) result3.setFont(new Font("黑体", Font.PLAIN, 22));else result3.setFont(new Font("Serif", 0, 30));if(result2.getText().length() >= 43) result2.setFont(new Font("黑体", Font.PLAIN, 18));else if(result2.getText().length() >= 31) result2.setFont(new Font("黑体", Font.PLAIN, 22));else result2.setFont(new Font("Serif", 0, 30));}
效果图

3.4 调整计算器整体界面
由于之前的程序界面看起来太大了,所以我做了适当调整
3.5 修改程序图标
ImageIcon icon = new ImageIcon("src/png.png");setIconImage(icon.getImage());
4. 项目总结
4.1 项目实现的功能以及作用
该入门项目利用java的awt工具包、Swing工具包,简单实现了计算器的基本功能,实现了Java面向对象的简单应用,程序可供平时计算使用,另外有进制转换功能。
4.2 项目存在的缺陷
- 没有小数运算以及带负数的运算功能
- 没有键盘操作功能
- 没有错误式子检测功能
- 代码不够精炼,排版较差
- 交互式不够贴切,使用体验差
- 功能较少,并且还未完善
…
4.3 心得体会
做之前还是信心满满的,觉得有能力做好这个计算器,但是在做的时候才发现出现了许多问题,我自己对类的继承、接口,方法重写不够熟练,在项目中遇到的问题大多时候都需要通过百度查阅资料处理,因为接触awt包和Swing包的时间太少,最终能完成项目还是很高兴的。
期间也有许多粗心的操作,比如计算值的时候入栈报错,结果只是定义栈的后面忘记new对象了。在最简单的类型转换也出了错,比如在进制转换时, 想让数字10 转成字母A,我用之前C++里的写法 直接用了加减,结果报了一大堆的错,后来想了半天才知道要定义新的变量才能强制转换,在Java里 字符之间的加号会变成字符串。
项目里有明显的BUG,留给以后解决,到时候还能回头复习一下。
总之,这一次项目是体验一下java的Swing包的感觉,其实还不错的,希望下次再接再厉,做出更好的项目。
最终代码
import java.awt.event.*;
import java.awt.image.ImageObserver;
import java.awt.image.ImageProducer;
import java.math.BigInteger;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.net.URL;class main {public static void main(String[] args) {JFrame frame = new CalJFrame("简 易 计 算 器");}
}class CalJFrame extends JFrame{//定义3个面板 以及 一个图片JPanel Picture = new JPanel(new BorderLayout());JPanel Result = new JPanel(new GridLayout(1, 1));JPanel Cal = new JPanel(new GridLayout(6, 5));JLabel head = new JLabel();// 定义一个计算类Calculate calculate = new Calculate();// 定义三个文本框JTextField result1 = new JTextField("普通模式");JTextField result2 = new JTextField("");JTextField result3 = new JTextField("0");boolean Record = false; //记录模式的开关/* 定义文本框的状态变量 */int state = 0; //0表示未计算,1表示计算中 2表示错误Stack<String> ress = new Stack<String>();//定义初始化面板函数public void iniPanel() {//固定画板的大小Cal.setPreferredSize(new Dimension(350, 320));Result.setPreferredSize(new Dimension(400, 40));head.setPreferredSize(new Dimension(400, 100));this.setBounds(1, 1, 500, 600);}//定义设置面板函数public void SetPanel() {//设置面板1 ----> 操作的按键面String[] title = {"(", ")", "<--", "CE", "Back", "7", "8", "9", "/", "记录", "4","5", "6", "*", "%", "1", "2", "3", "-", "Ave", "0", ".", "=", "+","σ", "10转n", "n转10", "n转2", "Pow", "√ ̄"};//列举按钮标题ButtonMonitor1 keyMonitor = new ButtonMonitor1();for (String temp : title) {JButton newButton = new JButton(temp);//设置按钮字体格式newButton.setFont(new Font("黑体", Font.PLAIN, 20));newButton.setActionCommand(temp); //设置命令为按钮标题newButton.addActionListener(keyMonitor);//添加监听事件Cal.add(newButton);}addKeyListener(new KeyAdapter() {/* 键盘 按下时 */@Overridepublic void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();System.out.println(keyCode);if(keyCode == KeyEvent.VK_UP){System.out.println("你按下了上键");}}});//设置面板2 ----> 顶部的图片head.setIcon(new ImageIcon("src/pic.jpg"));Picture.add(head);//设置面板3 ----> 结果显示界面Result.setLayout(new GridLayout(3, 1));//设置文本框字体格式Font x = new Font("Serif", 0, 30);result1.setFont(x);result2.setFont(x);result3.setFont(x);result1.setBackground(Color.WHITE);result2.setBackground(Color.WHITE);result3.setBackground(Color.WHITE);result1.setEditable(false);result2.setEditable(false);result3.setEditable(false);//设置文本框对其方式为--> 右对齐result1.setHorizontalAlignment(JTextField.RIGHT);result2.setHorizontalAlignment(JTextField.RIGHT);result3.setHorizontalAlignment(JTextField.RIGHT);Result.add(result1);Result.add(result2);Result.add(result3);//设置文本框2的监听事件result2.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {if (e.getActionCommand().equals("c1")) {result2.setText(TenToN(result3.getText(), result2.getText()));} else if (e.getActionCommand().equals("c2")) {result2.setText(NToTwo(result3.getText(), result2.getText()));} else if (e.getActionCommand().equals("c3")) {result2.setText(NToTen(result3.getText(), result2.getText()));} else if (e.getActionCommand().equals("c4")) {result2.setText(Powx(result3.getText(), result2.getText()));} else if (e.getActionCommand().equals("c5")) {result2.setText(SqrtPlus(result3.getText(), result2.getText()));} else if (e.getActionCommand().equals("c6")) {result2.setText(Average(result2.getText()));} else if (e.getActionCommand().equals("c7")) {result2.setText(Standard(result2.getText()));} else if (e.getActionCommand().equals("c8")) {result2.setText(modd(result2.getText()));}}});}public CalJFrame(String s){this.setTitle(s);Container container = this.getContentPane();iniPanel(); //初始化面板SetPanel(); //设置面板//添加面板进入窗口容器container.add(Picture,BorderLayout.NORTH);container.add(Result,BorderLayout.CENTER);container.add(Cal,BorderLayout.SOUTH);ImageIcon icon = new ImageIcon("src/png.png");setIconImage(icon.getImage());this.setVisible(true);}class ButtonMonitor1 implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {Define();String command = e.getActionCommand(); //读取按钮内容if(state == 0){result3.setText("");state = 1;}/* 单个按钮标题的 按钮处理*/if (command.length() == 1) {/* case 1: 处理按钮为数字 或者 运算符 */char cmd = command.charAt(0);if (cmd >= '0' && cmd <= '9' || cmd == '+' || cmd == '-' || cmd =='*' || cmd =='/' || cmd =='(' || cmd == ')') {result3.setText(result3.getText() + command);}/* case 2: 计算结果 */else if(cmd == '='){String res = Integer.toString(calculate.Result(result3.getText()));result3.setText(res);if(Record == true){result2.setText(result2.getText() + res + ",");}ress.push(res);state = 1;}else if(cmd == '%'){result1.setText("取模模式:%号隔开,前%后");if(!result3.getText().equals("0")) result2.setText(result3.getText() + '%');else result2.setText("");result2.setEditable(true);result2.setActionCommand("c8");}}/* 清零按钮处理*/else if(command.equals("CE")) {if(!result1.equals("记录模式开启"))result2.setText("");result1.setText("普通模式");result3.setText("0");state = 0;calculate.Operator.clear();calculate.Operand.clear();}else if(command.equals("<--")){String s = result3.getText();if(s.length() >= 1) s = s.substring(0, s.length()-1);if(s.equals("")){ result3.setText("0");state = 0;}else result3.setText(s);}else if(command.equals("10转n")) {result1.setText("在下方输入进制数,回车即可: ");result2.setText("");result2.setEditable(true);result2.setActionCommand("c1");}else if(command.equals("n转2")) {result1.setText("在下方输入进制数,回车即可: ");result2.setText("");result2.setEditable(true);result2.setActionCommand("c2");}else if(command.equals("n转10")) {result1.setText("在下方输入进制数,回车即可: ");result2.setText("");result2.setEditable(true);result2.setActionCommand("c3");}else if(command.equals("Pow")){result1.setText("在下方输入指数,回车即可: ");result2.setText("");result2.setEditable(true);result2.setActionCommand("c4");}else if(command.equals("√ ̄")){result1.setText("在下方输入开根数,回车即可: ");result2.setText("");result2.setEditable(true);result2.setActionCommand("c5");}else if(command.equals("Ave")){result1.setText("输入多组数据,用英文逗号隔开");result2.setText("");result2.setEditable(true);result2.setActionCommand("c6");}else if(command.equals("σ")){result1.setText("输入多组数据,用英文逗号隔开");result2.setText("");result2.setEditable(true);result2.setActionCommand("c7");}else if(command.equals("记录")){if(!result1.getText().equals("记录模式开启")) {result1.setText("记录模式开启");Record = true;result2.setEditable(false);}else {result1.setText("记录模式关闭");Record = false;}result2.setText("");}else if(command.equals("Back")){if(ress.empty()) {result3.setText("0"); state = 0;}else result3.setText(ress.pop());}}}class Calculate {public Stack <Integer> Operand = new Stack<Integer>(); //运算数栈public Stack <Character> Operator= new Stack<Character>(); //运算符栈public int Result(String s){char []c = s.toCharArray();int i = 0; //用于计数 , 存多位数的位数大小int []a = new int[30]; //存多位数的每一位//遍历计算式子for(int k = 0; k < c.length; k++){/* 先读取数字 */while(c[k] >= '0' && c[k] <= '9'){a[i++] = c[k] - '0';k++;if(k == c.length) break; // 特判最后一位数}if(i!=0){int num = 0;for(int j = 0; j < i; j++){num += a[j] * Math.pow(10, i - j - 1);a[j] = 0;}Operand.push(num); //读取多位数 入栈i = 0;if(k == c.length) break;}// Step 1: 考虑特殊情况: 空栈, 栈顶为左括号,或者 当前级数更大 直接入栈if(Operator.empty() || Operator.peek() == '(' || c[k] == '*' || c[k] =='/' || c[k] == '(') Operator.push(c[k]);/* Step 2: 遇到右括号 需要一直计算到下一个左括号为 止 */else if(c[k] == ')') {while (!Operator.empty() && Operator.peek() != '(') {CalOnce();}if(Operator.pop() != '(') state = 2; // 不存在左括号 则是错误式子}/* Step 3: 一般情况 */else {while(!Operator.empty() && IsSmall(c[k], Operator.peek())) {CalOnce();}Operator.push(c[k]);}}while (CalOnce() != -1) CalOnce(); /* 防止遗漏 */return Operand.peek();}public int CalOnce(){if(Operator.empty()) return -1; //不存在运算符则返回-1Character cmd = Operator.pop(); //读取运算符int b = Operand.pop();int a = Operand.pop();int c = 0;switch(cmd){case '+': c = a + b;break;case '-': c = a - b;break;case '*': c = a * b;break;case '/': c = a / b;break;default:break;}Operand.push(c);return c;}/* 用于判断 两运算符大小 */public boolean IsSmall(Character a, Character b){if(a == '+' || a == '-')return true;if(a == '*' || a == '/')return b == '*' || b =='/';return false;}}/* 十进制转化为其他进制 */public String TenToN(String num, String n){int []a = new int[100];char []s = num.toCharArray();int nn = Integer.parseInt(n);//将字符数组转化成数字int i = 0, sum = 0;for(int k = s.length - 1; k >= 0; k--){sum += (s[k] - '0') * Math.pow(10,i);i++;}i = 0;while(sum!=0){a[i++] = sum % nn;sum /= nn;}StringBuffer ss = new StringBuffer();while(i > 0){i--;if(a[i] <= 9) ss.append(a[i]);else {int b = a[i] - 10 + 65;ss.append((char)b);}}return "计算结果是:" + ss.toString();}/* 其他进制转化为十进制 */public String NToTen(String num, String n){int []a = new int[100];char []s = num.toCharArray();int nn = Integer.parseInt(n);//将字符数组转化成数字int i = 0, sum = 0;for(int k = s.length - 1; k >= 0; k--){if(s[k] >= 'A' && s[k] <= 'Z'){int b = s[k] - 65;sum += b * Math.pow(nn, i);}else sum += (s[k] - '0') * Math.pow(nn,i);i++;}return "计算结果是" + String.valueOf(sum);}/* 其他进制转化为二进制 */public String NToTwo(String num, String n){return TenToN(NToTen(num, n), "2");}public String Powx(String num, String n){int a = Integer.parseInt(num);int x = Integer.parseInt(n);return "计算结果是" + String.valueOf(Math.pow(a,x));}public String SqrtPlus(String num, String n){int a = Integer.parseInt(num);int x = Integer.parseInt(n);return "计算结果是" + String.valueOf(Math.pow(a,1.0 / x));}/* 求平均值方法*/public String Average(String num) {String[] strnum = num.split(","); // 字符串分割Double res = 0.0;for (int i = 0; i < strnum.length; ++i)res += Double.valueOf(strnum[i]);return String.valueOf(res / strnum.length);}/* 求标准差方法 */public String Standard(String num){String[] strnum = num.split(",");Double ave = Double.valueOf(Average(num));Double ans = 0.0;for (int i = 0; i < strnum.length; ++i)ans += Math.pow(Double.valueOf(strnum[i]) - ave , 2);return String.valueOf(Math.sqrt(ans / strnum.length));}/* 取模 方法 */public String modd(String num){String[] strnum = num.split("%");int a = Integer.valueOf(strnum[0]);int b = Integer.valueOf(strnum[1]);return a + "%" + b + "=" + String.valueOf(a % b);}public void Define(){if(result3.getText().length() >= 43) result3.setFont(new Font("黑体", Font.PLAIN, 18));else if(result3.getText().length() >= 31) result3.setFont(new Font("黑体", Font.PLAIN, 22));else result3.setFont(new Font("Serif", 0, 30));if(result2.getText().length() >= 43) result2.setFont(new Font("黑体", Font.PLAIN, 18));else if(result2.getText().length() >= 31) result2.setFont(new Font("黑体", Font.PLAIN, 22));else result2.setFont(new Font("Serif", 0, 30));}
}
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
