科学计算器(JAVA实现)
前记:
大二学 Java 的时候写的,现在贴上来,只为留念。
再翻代码,自己看着都头疼。一重重的 if 嵌套,当时写得费劲,现在看着更费劲。
代码思想:
代码的大致思想是这样:
首先定义一个算式字符串。然后用户通过键盘或鼠标点击按钮输入字符,添加到算式字符串末尾。在每次用户输入字符之后,先判断该字符是否符合算式语法规则(如加号后不能再跟加号),不符合语法规则的字符不添加到算式字符串末尾。如果用户输入了等号,则进行计算并将计算结果显示出来。
其中计算过程如下:
首先将字符串转化为两个链表,一个存储浮点数,一个存储运算符。
如 3 + 2*4 - 4/2
会被转换为两个链表: 3 2 4 4 2
+ * - /
之后循环以下过程:
在运算符链表中找到运算优先级最高的一个运算符(若有多个,取第一个)。假设其下标为 i(如在上例中,i = 1 ),然后在浮点数链表中找到下标为 i 和 i+1 的项,进行相应运算后,删除这两项,并把结果插入该位置。在运算符链表中删除该运算符。
如上例中,执行一次运算后,链表为: 3 8 4 2
+ - /
循环进行到浮点数链表中只有一个项目(也即操作符链表为空)。该项目即为算式计算结果。
经测试,程序能进行浮点数科学计算。能进行负数计算,如 3--3 。但是计算 3---3 时会出现异常。
代码:
Calculator.java
package mycalculator;
/*
*
* 计算3---3 会有异常
*
*
*
* */
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
public class Calculator extends JFrame implements ActionListener, KeyListener,
MouseListener {
final int WIDTH = 440, HEIGHT = 350;
GridLayout gridLayout = new GridLayout(4, 4, 5, 5); // 勿忘初始化 不初始化不会报错,但面板是空的
BorderLayout borderLayout = new BorderLayout();
FlowLayout flowLayout = new FlowLayout();
Container container;
// Container cont;
JPanel panel, buttonPanel;
JButton[] buttons;
String[] name;
JTextField textField;
boolean cleared = true;
public Calculator() {
super("Calculator");
container = getContentPane();
// Cont = getContentPane();
// Cont.setLayout(borderLayout);
buttonPanel = new JPanel();
panel = new JPanel();
// container = new Container();
// Cont.add(container, borderLayout.CENTER);
// panel.setSize(380,380);
buttonPanel.setLayout(gridLayout);
textField = new JTextField(15);
textField.setFont(textField.getFont().deriveFont(Font.BOLD,
(float) 32.0));
textField.setEditable(false);
textField.setHorizontalAlignment(JTextField.RIGHT);
textField.setBackground(Color.GRAY);
textField.setForeground(Color.WHITE);
panel.add(textField);
// textField.setSize(getBounds().width,getBounds().height/3);
// textField.setFont(textField.getFont().deriveFont(99));
/*
* container.setLayout(borderLayout); container.add(textField,
* borderLayout.NORTH); container.add(cont, borderLayout.CENTER);
*/
container.setLayout(borderLayout);
// container.add(textField);
container.add(panel, borderLayout.NORTH);
container.add(buttonPanel, borderLayout.CENTER);
// container.setSize(getBounds().width,getBounds().height);
// cont.setSize(getBounds().width,getBounds().height/3*2);
buttons = new JButton[16];
name = new String[] { "7", "8", "9", "/", "4", "5", "6", "*", "1", "2",
"3", "-", "0", ".", "=", "+" };
for (int index = 0; index <= 15; index++) {
buttons[index] = new JButton(name[index]);
buttons[index].addActionListener(this);
buttons[index].setBackground(Color.GRAY);
buttons[index].setForeground(Color.WHITE);
buttons[index].addKeyListener(this);
buttons[index].addMouseListener(this);
buttons[index].setFont(buttons[index].getFont().deriveFont(
Font.BOLD, (float) 32.0));
// buttons[index].setSize(200, 200);
buttonPanel.add(buttons[index]);
}
this.addKeyListener(this);
setSize(WIDTH, HEIGHT);
Toolkit kit = Toolkit.getDefaultToolkit(); // 定义工具包
Dimension screenSize = kit.getScreenSize(); // 获取屏幕的尺寸
int screenWidth = screenSize.width; // 获取屏幕的宽
int screenHeight = screenSize.height; // 获取屏幕的高
setLocation(screenWidth / 2 - WIDTH / 2, screenHeight / 2 - HEIGHT / 2);// 设置窗口居中显示
// setLocation(600, 250);
setVisible(true);
setFocusable(true);
}
String calculate(String str) {
String result = "Wrong Expression";
String temp = "";
if (str.charAt(0) != '-'
&& !(str.charAt(0) <= '9' && str.charAt(0) >= '0')) {
return result;
}
LinkedList<Double> list = new LinkedList<Double>();
LinkedList<Character> optList = new LinkedList<Character>();
Double doubleTemp;
boolean isFormerOpt = true;
for (int index = 0; index <= str.length() - 1; index++) {
if (index == 0) {
isFormerOpt = true;
} else {
if (str.charAt(index - 1) > '9' || str.charAt(index - 1) < '0') {
isFormerOpt = true;
} else {
isFormerOpt = false;
}
}
if (str.charAt(index) != '+' && str.charAt(index) != '*'
&& str.charAt(index) != '/'
&& (!(str.charAt(index) == '-' && isFormerOpt == false))) {
temp += str.charAt(index);
} else {
doubleTemp = new Double(temp);
list.add(doubleTemp);
temp = "";
optList.add(str.charAt(index));
}
}
doubleTemp = new Double(temp);
list.add(doubleTemp);
temp = "";
/*
* for (int index = 0; index <= list.size() - 1; index++) {
* System.out.println(list.get(index)); } for (int index = 0; index <=
* optList.size() - 1; index++) {
* System.out.println(optList.get(index)); }
*/
boolean isThereHigherOpt = true;
while (isThereHigherOpt == true) {
/*
* for (Iterator<Character> it = optList.iterator(); it.hasNext();)
* { if (it.next() == '*' || it.next() == '/') { isThereHigherOpt =
* true; int index = optList.indexOf(it.next());
*
* break; } }
*/
isThereHigherOpt = false;
for (int index = 0; index <= optList.size() - 1; index++) {
if (optList.get(index) == '*') {
Double t = list.get(index) * list.get(index + 1);
list.remove(index + 1);
list.set(index, t);
optList.remove(index);
isThereHigherOpt = true;
break;
}
if (optList.get(index) == '/') {
Double t = list.get(index) / list.get(index + 1);
list.remove(index + 1);
list.set(index, t);
optList.remove(index);
isThereHigherOpt = true;
break;
}
}
}
while (optList.isEmpty() == false) {
for (int index = 0; index <= optList.size() - 1; index++) {
if (optList.get(index) == '+') {
Double t = list.get(index) + list.get(index + 1);
list.remove(index + 1);
list.set(index, t);
optList.remove(index);
break;
}
if (optList.get(index) == '-') {
Double t = list.get(index) + 0.0 - list.get(index + 1);
list.remove(index + 1);
list.set(index, t);
optList.remove(index);
break;
}
}
}
/*
* System.out.println("/////////////////////////////////"); for (int
* index = 0; index <= optList.size() - 1; index++) { //
* System.out.println(index); System.out.println(list.get(index));
* System.out.println(optList.get(index));
* System.out.println(list.get(index + 1)); }
*/
if (list.size() == 1) {
result = list.get(0).toString();
}
return result;
}
void addText(char ch) {
if (cleared == true && ((ch <= '9' && ch >= '0'))) {
textField.setText("");
cleared = false;
}
String str = textField.getText();
if (ch != '=') {
if (str.length() > 0) {
if (str.charAt(str.length() - 1) <= '9'
&& str.charAt(str.length() - 1) >= '0') {
if (ch != '.') {
textField.setText(str + ch);
} else {
boolean isTherePoint = false;
int i = str.length() - 1;
while (i >= 0) {
if (str.charAt(i) == '*' || str.charAt(i) == '/'
|| str.charAt(i) == '+'
|| str.charAt(i) == '-') {
break;
}
if (str.charAt(i) == '.') {
isTherePoint = true;
break;
}
i--;
}
if (isTherePoint == false) {
textField.setText(str + ch);
}
}
} else {
if ((ch <= '9' && ch >= '0') || ch == '-') {
textField.setText(str + ch);
}
}
} else {
if (ch == '-' || (ch <= '9' && ch >= '0'))
textField.setText(str + ch);
}
cleared = false;
} else {
if (cleared == true) {
textField.setText("");
} else {
str = textField.getText();
//System.out.println(str);
textField.setText("");
if (str.length() > 0) {
if (str.charAt(str.length() - 1) <= '9'
&& str.charAt(str.length() - 1) >= '0') {
textField.setText(calculate(str));
} else {
textField.setText("Wrong Expression");
}
}
}
cleared = true;
}
}
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source.getClass() == JButton.class) {
JButton button = (JButton) source;
char ch = button.getText().charAt(0);
addText(ch);
}
}
public void keyPressed(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
char ch = e.getKeyChar();
if (ch == ' ') {
System.exit(EXIT_ON_CLOSE);
}
if (ch == KeyEvent.VK_ENTER) {
buttons[14].setBackground(Color.LIGHT_GRAY);
for (int i = 0; i <= name.length - 1; i++) {
if (i != 14) {
buttons[i].setBackground(Color.GRAY);
}
}
addText('=');
return;
}
for (int index = 0; index <= name.length - 1; index++) {
if (ch == name[index].charAt(0)) {
// System.out.println(ch);
buttons[index].setBackground(Color.LIGHT_GRAY);
for (int i = 0; i <= name.length - 1; i++) {
if (i != index) {
buttons[i].setBackground(Color.GRAY);
}
}
addText(ch);
break;
}
}
}
public void mouseClicked(MouseEvent event) {
}
public void mouseEntered(MouseEvent event) {
Object source = event.getSource();
if (source.getClass() == JButton.class) {
JButton button = (JButton) source;
// System.out.println("hey");
button.setBackground(Color.LIGHT_GRAY);
}
}
public void mousePressed(MouseEvent event) {
}
public void mouseReleased(MouseEvent event) {
}
public void mouseExited(MouseEvent event) {
Object source = event.getSource();
if (source.getClass() == JButton.class) {
JButton button = (JButton) source;
// System.out.println("hey");
button.setBackground(Color.GRAY);
}
}
public static void main(String[] args) {
Calculator c = new Calculator();
// c.addKeyListener(c);
c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
程序运行效果:
计算9/3-1*2+-1

结果:

随笔写于2016.4.8。
程序写于大二下学期,Java程序设计 课程期间。
END
科学计算器(JAVA实现)的更多相关文章
- 科学计算器的Java实现
简易的科学计算器的实现 ---Java版 import javax.swing.*;//新的窗口组件包 import java.awt.*; import java.awt.event.*; publ ...
- 想找个计算器当本命?来试试UWP应用《纸书科学计算器》
久违了.上次在博客园发文还是4年前,正是高中参加NOIP的时候.这4年里发生了很多事,乃至再次看到过去的文章时,仿佛看到了自己也不熟悉的风景.最近很想把我的博客重新拾起来,慢慢灌溉,写一些微不足道的技 ...
- 整理一些《纸书科学计算器》的小Tips
本文最开始是在2016年的文章 Win10应用<纸书科学计算器>更新啦! 发表之后撰写的,当时那篇文章收到了不少人点赞,应用在国内市场的日下载量也突然上涨,让我感到受宠若惊,这里要感谢Wp ...
- Win10应用《纸书科学计算器》更新啦!
<纸书科学计算器>在2016年8月拿了计算机设计大赛国家一等奖,现在仍记得我在答辩时还给评委们普及了一波UWP平台的知识.受此鼓励,这款应用也不会停下更新的脚步^_^.最近从1.9小幅升级 ...
- html+css+js实现科学计算器
代码地址如下:http://www.demodashi.com/demo/13751.html 项目描述 纯html+css+js实现一个科学计算器,支持平方开方指数对数等基本函数,支持键盘输入,有简 ...
- 《学习R》笔记:科学计算器、检查变量和工作区、向量、矩阵和数组、列表和数据框
一.第二章 科学计算器 要检查两个数字是否一样,要使用 all.equal() ,不要使用 == ,== 符号仅用于比较两个整型数是否存在相同 . > all.equal(sqrt(2)^2,2 ...
- 数据结构之栈—强大的四则复杂运算计算器(超过windows自带的科学计算器)【中缀转后缀表达式】
比windows自带计算器还强的四则复杂运算计算器! 实测随机打出两组复杂算式:-7.5 * 6 / ( -2 + ( -6.5 - -5.22 ) )与7.5+-3*8/(7+2) windows ...
- JS编写的科学计算器
最近半个月编写了一个JS+CSS+HTML的网页计算器,从最初的具有简陋界面的简单计算器改版到最终具有科学/标准计算器转换功能并且界面非常友好的计算器,收获良多!总的来说,代码简单,通俗易读,下面贴上 ...
- JavaScript实现科学计算器
运行效果: 可实现科学计算器的功能,如:PI,sin,cos,tan等 源代码: 1 <!DOCTYPE html> 2 <html lang="zh"> ...
随机推荐
- C#+ArcEngine10.0+SP5实现鼠标移动动态显示要素属性信息
为了解决鼠标移过动态显示要素属性的问题,我在网上先是查到的只能显示单个要素的属性,就是直接在arcmap中设置好的那个tips就可以显示,但是这种显示效果只是简单的实现了显示要素的属性值,可是没有对该 ...
- Hibernate 表映射 主键生成策略与复合主键
主要分析三点: 一.数据表和Java类的映射 : 二.单一主键映射和主键的生成策略 : 三.复合主键的表映射 : 一.数据表和Java类的映射 Hibernate封装了数据库DDL语句,只需要将数据 ...
- UVALive 6916---Punching Robot(卢卡斯+容斥)
题目链接 https://icpcarchive.ecs.baylor.edu/index.php?option=com_onlinejudge&Itemid=8&page=show_ ...
- Lind.DDD.Authorization用户授权介绍
回到目录 Lind.DDD.Authorization是Lind.DDD框架的组成部分,之所以把它封装到框架里,原因就是它的通用性,几乎在任何一个系统中,都少不了用户授权功能,用户授权对于任何一个系统 ...
- 轻量的、可自定义 CSS 的 Lightbox 相册插件
jQuery LightGallery是一个轻量级的,可定制的,模块化的,响应式的 jQuery 相册插件.它采用 CSS 来实现图像和视频的大小调整.因此,这将是非常灵活的,并且比使用 JavaSc ...
- 使用requireJS的shim参数 解决插件 jquery.ui 等插件问题
没有requireJS框架之前,如果我们想使用jquery框架,会在HTML页面中通过<script>标签加载, 这个时候jquery框架生成全局变量$和jQuery等全局变量.如果项目中 ...
- TFS online 自动部署配置
概要 采用tfs online进行源码管理,并配置自动编译部署到外网上一台服务器上(阿里云虚拟机) 步骤; 下载angent,并运行脚本安装 配置release managemetn; 1)Copy ...
- Google C++单元测试框架GoogleTest---GTest的Sample1和编写单元测试的步骤
如果你还没有搭建gtest框架,可以参考我之前的博客:http://www.cnblogs.com/jycboy/p/6001153.html.. 1.The first sample: sample ...
- IOS开发基础知识--碎片15
1:将自定义对象转化成NsData存入数据库 要转为nsdata自定义对象要遵循<NSCoding>的协议,然后实现encodeWithCoder,initwithcode对属性转化,实例 ...
- IE10 和 Chrome50 对日期 new Date() 支持的区别
IE10 和 Chrome50 对日期 new Date() 支持的区别: new Date('2016-06-18'); // IE10 不通过.Chrome 通过 new Date('2016/0 ...