java下载过程Java编写简单计算器的完整实现过程
⽬录
前⾔
⼀、具体功能:
⼆、主要思想:
三、结果测试
四、完整源代码(每⾏代码已附有详细注释)
前⾔
本⽂⽤Java的swing来实现⼀个简单计算器,主要内容为图形⽤户界⾯GUI的实现以及运算表达式核⼼算法的设计编写。
程序运⾏环境为Windows10 ,编译环境为MyEclipse 。
⼀、具体功能:
1、:输⼊,输出
输⼊:允许输⼊带有括号的完整计算式(例 8*(4-95)+5÷2*e-pi)
js两个数组去重输出:输出Double类型的结果
输出:整个运算表达式并保存于历史记录中
2、:功能
基本的加,减,乘,除,四则运算
平⽅运算
开⽅运算
求余运算
最终界⾯如下图:
除了常规的数字按钮和运算符,还有两个常数e,pi(π),清空键AC,括号运算符(),平⽅(x^x)和开⽅(sqrt)运算符,输⼊显⽰框以及历史记录⽂本框,⽂本框的垂直滚动条和⽔平滚动条。
⼆、主要思想:
1:中缀表达式转为后缀表达式
准备:
①后缀表达式队列:postQueue,⽤于存储逆波兰表达式(其实不⽤队列排序直接输出也⾏)
②操作符栈:opStack,对⽤户输⼊的操作符进⾏处理,⽤于存储运算符
算法思想:
从左向右依次读取算术表达式的元素X,分以下情况进⾏不同的处理:
(1)如果X是操作数,直接⼊队
(2)如果X是运算符,再分以下情况:
b)如果X==”(“,直接⼊栈。
c)如果X==”)“,则将栈⾥的元素逐个出栈,并⼊队到后缀表达式队列中,直到第⼀个配对的”(”出栈。(注:“(”和“)”都不⼊队)
d)如果是其他操作符(+ - * /),则和栈顶元素进⾏⽐较优先级。如果栈顶元素的优先级⼤于等于X,则出栈并把栈中弹出的元素⼊队,直到栈顶元素的优先级⼩于X或者栈为空。弹出完这些元素后,才将遇到的操作符压⼊到栈中。
(3)最后将栈中剩余的操作符全部⼊队。
⽰意图:
2、计算后缀表达式
准备:
需要⽤到⼀个结果栈Res_Stack :⽤于存放计算的中间过程的值和最终结果
算法思想:
1、从左开始向右遍历后缀表达式的元素。
2、如果取到的元素是操作数,直接⼊栈Res_Stack,如果是运算符,从栈中弹出2个数进⾏运算,然后把运算结果⼊栈
3、当遍历完后缀表达式时,计算结果就保存在栈⾥了。
⽰意图:
三、结果测试
分析:
1、可实现基本四则运算及平⽅、开⽅、求余运算。
2、运算表达式可显⽰于输⼊界⾯并保存于历史记录栏
3、输⼊界⾯和历史记录栏皆可实现不断字⾃动换⾏功能以及滚动条功能
4、不⾜之处:进⾏平⽅和开⽅运算时其保存在历史记录中的表达式会出现两个等号及两个结果。
四、完整源代码(每⾏代码已附有详细注释)
package software;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
//Calculator类,继承JFrame框架,实现事件接⼝
public class Calculator extends JFrame implements ActionListener {
private String[] KEYS = { "7", "8", "9", "AC", "4", "5", "6", "-", "1", "2", "3", "+", "0", "e", "pi", "/", "sqrt",
"%", "x*x", "*", "(", ")", ".", "=" };
java简单小游戏编程源代码private JButton keys[] = new JButton[KEYS.length];
private JTextArea resultText = new JTextArea("0.0");// ⽂本域组件TextArea可容纳多⾏⽂本;⽂本框内容初始值设为0.0  private JTextArea History = new JTextArea();// 历史记录⽂本框初始值设为空
private JPanel jp1=new JPanel();
private JPanel jp2=new JPanel();
private JScrollPane gdt1=new JScrollPane(resultText);//给输⼊显⽰屏⽂本域新建⼀个垂直滚动滑条
private JScrollPane gdt2=new JScrollPane(History);//给历史记录⽂本域新建⼀个垂直滚动滑条
// private JScrollPane gdt3=new JScrollPane(History);//给历史记录⽂本域新建⼀个⽔平滚动滑条
private JLabel label = new JLabel("历史记录");
private String b = "";
// 构造⽅法
public Calculator() {
super("Caculator");//“超”关键字,表⽰调⽤⽗类的构造函数,
resultText.setBounds(20, 18, 255, 115);// 设置⽂本框⼤⼩
resultText.setAlignmentX(RIGHT_ALIGNMENT);// ⽂本框内容右对齐
resultText.setEditable(false);// ⽂本框不允许修改结果
History.setBounds(290, 40, 250,370);// 设置⽂本框⼤⼩
History.setAlignmentX(LEFT_ALIGNMENT);// ⽂本框内容右对齐
History.setEditable(false);// ⽂本框不允许修改结果
label.setBounds(300, 15, 100, 20);//设置标签位置及⼤⼩
jp2.setBounds(290,40,250,370);//设置⾯板窗⼝位置及⼤⼩
jp2.setLayout(new GridLayout());
jp1.setBounds(20,18,255,115);//设置⾯板窗⼝位置及⼤⼩
jp1.setLayout(new GridLayout());
resultText.setLineWrap(true);// 激活⾃动换⾏功能
resultText.setWrapStyleWord(true);// 激活断⾏不断字功能
resultText.setSelectedTextColor(Color.RED);
History.setLineWrap(true);//⾃动换⾏
History.setWrapStyleWord(true);
History.setSelectedTextColor(Color.blue);
gdt1.setViewportView(resultText);//使滚动条显⽰出来
gdt2.setViewportView(History);
gdt1.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条⼀直显⽰
gdt2.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);//设置让垂直滚动条⼀直显⽰
gdt2.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);//设置让⽔平滚动条⼀直显⽰
jp1.add(gdt1);//将滚动条添加⼊⾯板窗⼝中
jp2.add(gdt2);using namespace std报错
this.add(jp1);//将⾯板添加到总窗体中
this.add(jp2);//将⾯板添加到总窗体中
this.setLayout(null);
this.add(label);// 新建“历史记录”标签
//this.add(resultText);// 新建⽂本框,该语句会添加进去⼀个新的JTextArea导致带有滚动条的⽂本⽆法显⽰或者发⽣覆盖 //this.add(History);// 新建历史记录⽂本框,该语句会添加进去⼀个新的JTextArea导致带有滚动条的⽂本⽆法显⽰
// 放置按钮
int x = 20, y = 150;
for (int i = 0; i < KEYS.length; i++)
{
keys[i] = new JButton();
keys[i].setText(KEYS[i]);
keys[i].setBounds(x, y, 60, 40);
if (x < 215) {
x += 65;
} else {
x = 20;
y += 45;
}
this.add(keys[i]);
}
for (int i = 0; i < KEYS.length; i++)// 每个按钮都注册事件
{
keys[i].addActionListener(this);
}
this.setResizable(false);
this.setBounds(500, 200, 567, 480);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
}
// 事件处理
public void actionPerformed(ActionEvent e)
{
//History.setText(b);//使输⼊的表达式显⽰在历史记录⽂本框中
String ActionCommand();//获得事件源的标签
if(label=="=")//
{
resultText.setText(this.b);
History.Text()+Text());
if(label=="=")//调⽤计算⽅法,得出最终结果
{
String s[]=houzhui(this.b);
String result=Result(s);
this.b=result+"";
//更新⽂本框,当前结果在字符串b中,并未删除,下⼀次输⼊接着此结果以实现连续运算
resultText.setText(this.b);
History.Text()+"="+Text()+"\n");
}
}
else if(label=="AC")//清空按钮,消除显⽰屏⽂本框前⾯所有的输⼊和结果
{
this.b="";
resultText.setText("0");//更新⽂本域的显⽰,显⽰初始值;
}
else if(label=="sqrt")
{
String n=kfys(this.b);
resultText.setText("sqrt"+"("+this.b+")"+"="+n);//使运算表达式显⽰在输⼊界⾯
History.Text()+"sqrt"+"("+this.b+")"+"=");//获取输⼊界⾯的运算表达式并使其显⽰在历史记录⽂本框  this.b=n;
else if(label=="x*x")
{
String m=pfys(this.b);
resultText.setText(this.b+"^2"+"="+m);//使运算表达式显⽰在输⼊界⾯
History.Text()+this.b+"^2"+"=");//获取输⼊界⾯的运算表达式并使其显⽰在历史记录⽂本框  this.b=m;
}
else if(label=="e"||label=="pi")
{
if(label=="e")
{
String m=String.valueOf(2.71828);//将e的值以字符串的形式传给m
this.b=this.b+m;//保留显⽰m之前输⼊的运算符或数字字符继续下⼀步运算
resultText.setText(this.b);
// History.Text()+this.b);
}
if(label=="pi")
{
String m=String.valueOf(3.14159265);
this.b=this.b+m;
resultText.setText(this.b);
/
/ History.Text()+this.b);
}
}
else
{
this.b=this.b+label;
resultText.setText(this.b);
// History.Text()+this.b);
}
//History.Text()+this.b);//使输⼊的表达式显⽰在历史记录⽂本框中
}
/
/将中缀表达式转换为后缀表达式
private String[] houzhui(String str) {
String s = "";// ⽤于承接多位数的字符串
char opStack[] = new char[100];// 静态栈,对⽤户输⼊的操作符进⾏处理,⽤于存储运算符
String postQueue[] = new String[100];// 后缀表达式字符串数组,为了将多位数存储为独⽴的字符串
int top = -1, j = 0;// 静态指针top,控制变量j
for (int i = 0; i < str.length(); i++)// 遍历中缀表达式
// indexof函数,返回字串⾸次出现的位置;charAt函数返回index位置处的字符;
{
if ("0123456789.".indexOf(str.charAt(i)) >= 0) // 遇到数字字符的情况
{
s = "";// 作为承接字符,每次开始时都要清空
for (; i < str.length() && "0123456789.".indexOf(str.charAt(i)) >= 0; i++) {
s = s + str.charAt(i);
}
i--;
爱阅小说json解析失败postQueue[j] = s;// 数字字符直接加⼊后缀表达式
j++;
} else if ("(".indexOf(str.charAt(i)) >= 0) {// 遇到左括号
top++;
opStack[top] = str.charAt(i);// 左括号⼊栈
} else if (")".indexOf(str.charAt(i)) >= 0) {// 遇到右括号
for (;;)// 栈顶元素循环出栈,直到遇到左括号为⽌
{
continue语句不能跳出最外层循环if (opStack[top] != '(') {// 栈顶元素不是左括号
postQueue[j] = opStack[top] + "";// 栈顶元素出栈
j++;
top--;
} else { // 到栈顶元素是左括号
top--;// 删除栈顶左括号
break;// 循环结束
}
}
}
if ("*%/".indexOf(str.charAt(i)) >= 0)// 遇到⾼优先级运算符
{
if (top == -1) {// 若栈为空则直接⼊栈
top++;
opStack[top] = str.charAt(i);
} else {// 栈不为空,把栈中弹出的元素⼊队,直到栈顶元素优先级⼩于x或者栈为空
if ("*%/".indexOf(opStack[top]) >= 0) {
// 栈顶元素也为⾼优先级运算符
postQueue[j] = opStack[top] + "";// 栈顶元素出栈进⼊后缀表达式
j++;
opStack[top] = str.charAt(i);// 当前运算符⼊栈
} else if ("(".indexOf(opStack[top]) >= 0) {// 栈顶元素为左括号,当前运算符⼊栈
top++;
opStack[top] = str.charAt(i);
} else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低优先级运算符
postQueue[j] = opStack[top] + "";// 栈顶元素出栈进⼊后最表达式
j++;
opStack[top] = str.charAt(i);// 当前元素⼊栈
}
}
} else if ("+-".indexOf(str.charAt(i)) >= 0) {
if (top == -1) {
top++;
opStack[top] = str.charAt(i);
} else {
if ("*%/".indexOf(opStack[top]) >= 0) {
// 栈顶元素也为⾼优先级运算符
postQueue[j] = opStack[top] + "";// 栈顶元素出栈进⼊后缀表达式
j++;
opStack[top] = str.charAt(i);// 当前运算符⼊栈
} else if ("(".indexOf(opStack[top]) >= 0) {// 栈顶元素为左括号,当前运算符⼊栈
top++;
opStack[top] = str.charAt(i);
} else if ("+-".indexOf(str.charAt(i)) >= 0) {// 遇到低优先级运算符
postQueue[j] = opStack[top] + "";// 栈顶元素出栈进⼊后最表达式
j++;
opStack[top] = str.charAt(i);// 当前元素⼊栈

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