首页 > 其他分享 >计算器软件开发

计算器软件开发

时间:2023-10-13 14:26:54浏览次数:41  
标签:String 软件开发 计算器 添加 操作符 按钮 new 表达式

用Java实现计算器软件设计

Java编写个人计算器软件

一、所需要实现的功能

1.该计算器需要实现加、减、乘、除、开平方功能。

2.需要有一个运行的UI界面,可以和电脑自带的计算器相比较。

该界面要有一个文本输入框,用来显示输入的表达式;

若干个按钮,用来用来显示数字以及操作符;

当点击按钮时,按钮上面对应的文本要显示在文本输入框中,并完成计算。

二、项目思想

1.通过Java Swing包和Java awt包完成计算器的基本运算和UI界面的设计,达到美观以及方便运用。

2.通过将日常熟悉的中缀表达式转换成符合计算机运算规则的后缀表达式,这里会涉及到栈、数组和集合的数据结构与算法。

三、字符串的拆分

因为表达式的输入是以字符串的形式输入进去的,即一整个表达式是一个字符串,在将中缀表达式转换为后缀表达式时,需要将长字符串拆分成短字符串,也就是说一个数字是一个字符串,一个操作符也是一个字符串。当有小数输入时要特别注意,要判断最后有没有溢出。

四、中缀表达式转换为后缀表达式步骤

  1.先创建一个字符栈,用于保存操作符;在创建一个数组,用于保存后缀表达式。

  2.按照从左至右的顺序遍历表达式,

(1)如果遇到的字符为操作数,则直接进入数组;

(2)如果遇到的是操作符,则进行以下判断:

如果栈为空:操作符就直接入栈;

如果栈不为空:那就判断遇到的字符和栈顶元素的优先级,

如果遇到的操作符优先级高于栈顶元素优先级,遇到的操作符便入栈;

否则(遇到的操作符优先级小于等于栈顶元素),栈顶元素出栈,并追加到后缀表达式中,直到栈顶元素优先级小于遇到的操作符优先级,或者栈为空时停止出栈,最后将遇到的操作符入栈。

(3)如果遇到左括号“( ”,则直接入栈。

(4)如果遇到右括号“ )”,则栈中元素依次出栈,并追加到后缀表达式,直到左括号出栈为止(左括号不追加到后缀表达式)。

(5)当表达式扫描完后,检查一遍栈是否为空,若不为空,则将栈中元素依次出栈,并追加到后缀表达式中。

五、UI界面设计

  涉及到界面设计时,Java有一个专门的UI设计工具类JFarme,在这个包下面我们可以进行UI界面的设计,比如窗口的创建与设置、控制面板的创建与设置,按钮的创建与设置,文本框的创建与设置,还有为按钮添加事件,来指定该按钮的作用。

六、详细代码

### 1.先写一个工具类calculate,用来存放计算器实现的功能

 

#### 1.1 将数学表达式拆分

~~~

private static List<String> split(String num) {// 返回值为数组list

List<String> list = new ArrayList<>();//List是一个集合

int len = num.length();

 

int start = 0;

int end = 0;

 

for (int i = 0; i < len; i++) {// i表示当前索引,指向一个个的字符

char tmp = num.charAt(i);// 获取当前字符

if (isOperator(tmp)) {// 如果tmp是运算符,就入栈

list.add(tmp + "");

continue;

}

// 如果是数字或者小数点

start = i;// start表示指向一个小数的开始,例:2.3的2

// if(i+1<len) {//判断是否还有下一个字符

// char next=num.charAt(i+1);//获取当前字符;

// //最后i+1可能会出现越界行为,

// //此时在外面再加一个判断语句,当i+1<len即不越界时

// //才判断next指向的是不是运算符

// while(i<len && !isOperator(next)) {

// i++;

// if(i+1>=len) break;//如果越界则退出循环,所有字符也都遍历结束

// next=num.charAt(i+1);

// }

// }

 

// 对上面部分做出优化

while (i + 1 < len && !isOperator(num.charAt(i + 1))) {

i++;

}

 

String str = num.substring(start, i + 1);// 字符串截取,得到小数5.2

list.add(str);// 把获得的小数添加到栈

 

}

return list;

}

 

~~~

#### 1.2 将拆分后的表达式转换为后缀表达式

 

这里我们就会需要到前面所说的后缀转化的方法,其中会涉及到栈、数组、队列的相关知识,忘了的小伙伴就要翻翻之前的数据结构了呦!

 

~~~

private static List<String> toPostfix(String num){

List<String> list=split(num);//获取表达式的各个元素

 

List<String> exp=new ArrayList<>(list.size()); //用于保存后缀表达式

 

//运算符暂存在栈中,数值保存在数组中

Stack<String> optStack=new Stack<>();//暂存运算符

 

//遍历集合中分割后的表达式(操作符或运算符)

for(String e:list ) {

//一、如果是操作数

if(!isOperator(e)){

exp.add(e);//添加

continue;

}

//二、如果是操作符

//1.如果栈为空,操作符入栈

if(optStack.isEmpty()) {

optStack.push(e);

continue;

}

//2.如果栈不为空,查看栈顶元素

String top=optStack.peek(); //查看栈顶元素

//2.1如果遇到的操作符元素的优先级高于栈顶元素,待入栈操作符入栈

if(judgePriority(e,top)) {//遇到的>栈顶,true

optStack.push(e);//入栈

continue;

}

//2.2否则(遇到的操作符优先级<=栈顶操作符优先级),栈顶元素出栈,

// 直到栈顶元素优先级小于遇到的操作符,或者栈为空时停止出栈

while(!optStack.isEmpty() && !judgePriority(e,top)) {

exp.add(top);//操作符入数组,跟在操作数后面

optStack.pop();//栈顶出栈

if(optStack.size()>0) {

top=optStack.peek();

}

 

}

 

//将当前操作符入栈

optStack.push(e);

 

}

 

//栈不为空,剩余操作符全部出栈,追加到后面

while(!optStack.isEmpty()) {

exp.add(optStack.pop());

}

 

return exp;

}

~~~

 

#### 1.3 通过后缀表达式得到结果

~~~

private static String getResultByPostFix(List<String> exp) {

//遍历集合中的元素

for(int i=0;i<exp.size();i++) {

String val=exp.get(i);//获取当前的元素

if(!isOperator(val)) {//如果当前元素是操作数,则继续遍历

continue;

}

//如果是运算符,则把该操作符前两位数进行计算

double result=0;

double prevOne=Double.parseDouble(exp.get(i-1));//获取操作符前一个数

double prevTwo=Double.parseDouble(exp.get(i-2));//前二的数

//判断运算符类型

switch(val) {

case "+":

result=prevOne+prevTwo;

break;

case "-":

result=prevOne-prevTwo;

break;

case "*":

result=prevOne*prevTwo;

break;

case "/":

result=prevOne/prevTwo;

break;

}

 

/* 计算完后,这三个字符串就要退出,不再参与

 * 原来的操作符位置i被新的结果result替换,+""是因为都是字符串

 * 原来的操作数退出

 * 下标i变为i-2;

 */

exp.set(i, result+"");//替换

exp.remove(i-1);//移除

exp.remove(i-2);//移除

i=i-2;

 

}

return exp.get(0);

}

 

~~~

 

#### 1.4 操作符优先级的判断

 

~~~

/* 判断运算符优先级

 * opt1优先级>opt2,则为true

 * opt1优先级<=opt2,则为false

 */

private static boolean judgePriority(String opt1,String opt2) {

if( eq(opt1,"+","-")) {

return false;//opt1"+或-" <= opt2"*或/"

 

}

 

if(eq(opt2,"+","-")) {

return true;//opt1"*或/" > opt2"+或-"

}

 

return false;//opt1"*或/" = opt2"*或/"

 

 

 

}

~~~

这里我写了一个eq方法,用来判断是否有两个元素相等,就可以简化上面if语句的判断条件,不然就会写一大串,看起来比较麻烦。

~~~

//public用于判断strs是否存在一个元素和src相等,只要存在一个相等则返回true

public static boolean eq(String src,String...strs) {//strs是一个数组

for(String str:strs) {

if(src.equals(strs)) {

return true;

}

}

 

return false;

}

 

 

2.UI界面的实现

完成了前面的计算器的计算原理,难道我们每次都要在运行窗口去计算吗?这也太麻烦了对不对,嗯!是的呢!那么......激动人心到时候来啦!接下来就要设计好看的计圈器界面了。

#### 2.1 窗口的创建

这里我对比了电脑自带的计算器,参考他的布局做了自己的计算器界面。第一张图片是电脑自带的计算器,第二张是自己做的计算器界面,由于功能比较少,所以大家不要嫌弃哈!

 

 

//设置窗口名字

this.setTitle("我的个人计算器");

//设置窗口大小

this.setSize(400, 500);

 

//设置窗口不可改变大小

this.setResizable(false);

 

//设置窗口可视化

this.setVisible(true);

//设置窗口关闭

this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

//DISPOSE_ON_CLOSE:点击右上角的“X”只关闭当前窗口,

//EXIT_ON_CLOSE:结束窗口所在的应用程序。在窗口被关闭的时候会退出JVM,软件所有窗口都会关闭

 

~~~

#### 2.2 添加文本框

 

~~~

//创建输入框

display=new JTextField();

//设置输入框宽高

display.setPreferredSize(new Dimension(400,50));

//设置输入框字体类型,样式,大小

display.setFont(new Font("Arail",Font.PLAIN,20));

//设置文本对齐方式,右对齐

display.setHorizontalAlignment(SwingConstants.RIGHT);

//设置边距

display.setMargin(new Insets(10,10,10,10));

//将输入框添加到窗口

this.add(display,BorderLayout.NORTH);

~~~

 

#### 2.3 添加按钮

 

  因为添加的按钮比较多,且按钮的功能不同,0~9这十个数字以及加减乘除、小数点这些只需要点击时输入文本就行,不需要实质的运算,当然这里的实质运算是在calcuater工具类完成的,因此只需要把它输进去就行,可以批量添加事件;而“清除”“删除”“等于”这些就需要在点击后立即做出反应,所以是要单独添加事件的。

 

~~~

//创建按钮,添加事件

private JButton creatButton(String text) {

return creatButton(text,true);

}

 

//该方法用于,创建按钮

//flag=true添加事件,否则不添加

private JButton creatButton(String text,boolean flag) {

JButton btn=new JButton(text);//创建按钮,并指定文本内容

btn.setFont(new Font("Arail",Font.PLAIN,20));

 

//增加一个事件,让文本显示在输入框(所以输入框的定义也要放在之前)

if(flag) {

btn.addActionListener(new ActionListener() {

 

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

String msg=display.getText();//获取文本

display.setText(msg+text);//拼接,点一个数字输入一个数字

 

}

 

});

}

 

return btn;

}

//该方法用于,批量把按钮添加到面板,把js添加到com中

private void addToComponent(JComponent com,JComponent...js) {

for(JComponent j:js) {

com.add(j);

}

}

 

~~~

  按钮要在控制面板上才会起作用,所以还要创建面板,一定要把按钮添加到面板中,不然它是不会显示出来的!

~~~

//创建控制面板

JPanel panel=new JPanel();

//分割区域

panel.setLayout(new GridLayout(5,4));

//添加按钮

for(int i=0;i<10;i++) {

JButton btn=creatButton(i+"");//添加数字按钮

btn.setFont(new Font("Arail",Font.PLAIN,20));//设置字体,样式,大小

panel.add(btn);//把按钮添加到面板中

 

}

JButton add=creatButton("+");

JButton substract=creatButton("-");

JButton multiply=creatButton("*");

JButton divide=creatButton("/");

JButton point=creatButton(".",true);//小数点

JButton eq=creatButton("=",false);

JButton clear=creatButton("c",false);//清除,整体删除

JButton del=creatButton("x",false);//删除,一个字符一个字符删

//批量添加按钮到面板

addToComponent(panel,add,substract,multiply,divide,point,eq,clear,del);

 

//把面板添加到窗口中

this.add(panel, BorderLayout.CENTER);

~~~

 

### 2.4 给按钮添加事件

 

  给按钮添加事件的意思就是,点击这个按钮之后会有什么样的反应,对于特别的按钮就需要一个个的添加了。

  给”清除”添加事件

~~~

clear.addActionListener(new ActionListener() {

 

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

display.setText("");

 

}

 

});

~~~

   给“删除”添加事件

~~~

del.addActionListener(new ActionListener() {

 

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

String msg=display.getText();//获取文本

if(msg.length()>0) {//有输入时才删除

display.setText(msg.substring(0,msg.length()-1));

 

}

 

}

 

});

~~~

  给“等于”添加事件

~~~

eq.addActionListener(new ActionListener() {

 

@Override

public void actionPerformed(ActionEvent e) {

// TODO Auto-generated method stub

if(display.getText().length()>0) {

String result=calculatorUtils.start(display.getText());

display.setText(result);

}

}

 

 

});

 

~~~

 那么经过上面的一系列操作,我们的计算器软件大概就做好了,如果想让我们的计算器更加美观,那么就需要多学习学习UI界面设计的一些知识了,不过设计一个基本的样式这些就大概足够了。

## 七、总结与心得

 

  在做这个软件之前,可以说是从来没有完完整整的做出一个软件,之前的课程虽然学了很多,这些内容也是学过的,或者多多少少了解过一点边缘化对象,但是自己没有把知识体系建立起来,感觉像是一段一段的记忆在自己脑子里乱窜,没有秩序的胡乱用,给我一种学了很多但又不知道学了什么的错觉。通过这个小软件的设计与开发我感觉自己收获良多!

 

标签:String,软件开发,计算器,添加,操作符,按钮,new,表达式
From: https://www.cnblogs.com/bbqiqi/p/17761975.html

相关文章

  • 软件开发人员 Kubernetes 入门指南|Part 2
    在第1部分中,我们讲解了Kubernetes的核心组件,Kubernetes是一种开源容器编排器,用于在分布式环境中部署和扩展应用程序;我们还讲解了如何在集群中部署一个简单的应用程序,然后更改其副本数量以扩大或缩小其规模。 在本文中,我们将为您深入讲解Kubernetes提供的网络和监控功能,......
  • 用Java实现计算器软件设计
    Java编写个人计算器软件一、所需要实现的功能1.该计算器需要实现加、减、乘、除、开平方功能。2.需要有一个运行的UI界面,可以和电脑自带的计算器相比较。该界面要有一个文本输入框,用来显示输入的表达式;若干个按钮,用来用来显示数字以及操作符;当点击按钮时,按钮上面对应的文本......
  • 汇编实战!手把手教你从“计算器”入门汇编语言
    基于汇编语言的简单整数计算器设计与实现 (此代码仅供学习使用,请勿用作其他用途)摘要本论文介绍了一款使用汇编语言编写的简单整数计算器程序,该程序支持基本的四则运算操作,并能处理包含括号的数学表达式。本文通过分析程序的代码结构,宏定义、数据段、子程序以及关键功能的实......
  • 可实现加、减、乘、除、开平方的计算器软件的实验设计
    可实现加、减、乘、除、开平方的计算器软件的实验设计1、思路代码:#include<stdio.h>#include<math.h>//牛顿迭代法计算平方根doublesqrt_newton(doublex){doubleguess=x/2.0;//初始猜测值为x的一半doubledelta=0.000001;//误差范围while(fabs(guess*gues......
  • 软件开发人员 Kubernetes 入门指南|Part 1
    Kubernetes是一个用于部署和管理容器的编排系统。使用Kubernetes,用户可以通过自动执行管理任务(例如在跨节点间扩展容器并在容器停止时重新启动任务),在不同环境中可靠地运行容器。 Kubernetes提供的抽象可以让你从Pod(容器)、Services(网络端点)和Jobs(一次性任务)等应用组件的角度......
  • 工程实践之高精度计算器
    说明本代码使用easyx绘制计算器界面,同时使用高精度算法实现大整数的连续运算前提准备需要安装easyx图形库,具体安装和使用流程请点击链接查看代码怎么用需要新建一个工程,向工程中添加头文件和源代码,或者先把所有头文件都提取出来放到一个新的cpp(虽然是c语言,但是easyx底层实现用......
  • 软件开发项目管理体系,支撑体系,测试体系文档大全
    在软件开发过程中,文档起着至关重要的作用。它不仅记录了项目或产品的基本信息,而且还是团队成员之间沟通的重要媒介。本文将详细介绍软件开发文档的作用、结构、撰写方法以及审校步骤,以帮助读者更好地理解和应用文档在软件开发中的价值。一、认识文档文档是软件开发过程中的产物......
  • 软件开发项目文档系列之一文档综述
    前言在当今数字时代,软件项目已经成为企业和组织实现业务目标的关键工具。然而,要确保软件项目的成功,除了高质量的代码和卓越的技术团队之外,文档的重要性也不可忽视。软件项目文档是项目的桥梁,它们连接了项目的各个阶段,记录了关键信息,帮助各方了解项目的需求、设计、开发、测试和部......
  • Metamon元兽app软件开发功能
    游戏行业也一直都是热门的行业,而元兽游戏app刚出现就得到不少用户的加入,该游戏是以优质的画面,机制完善,便捷的游戏体验,让用户在手机上体验不同的玩法。功能介绍元兽游戏app软件功能齐全,包括以下几点:1.游戏下载与更新:游戏的更新,用户在app浏览,下载上,更新等游戏中,游戏的角色,扮演,动作......
  • Langchain-Chatchat项目:3-Langchain计算器工具Agent思路和实现
      本文主要讨论Langchain-Chatchat项目中自定义Agent问答的思路和实现。以"计算器工具"为例,简单理解就是通过LLM识别应该使用的工具类型,然后交给相应的工具(也是LLM模型)来解决问题。一个LLM模型可以充当不同的角色,要把结构化的Prompt模板写好,充分利用LLM的Zero/One/Few-Shot能力......