结队编程项目——四则运算

一、项目需求

  • 自动生成小学四则运算题目(加、减、乘、除)统计正确率

    • 支持整数
    • 支持多运算符(比如生成包含100个运算符的题目)
    • 支持真分数

需求分析:

生成四则运算:需要使用随机数生成,需要创造一个能实现计算功能的类。

支持多运算符:运算符也需要利用随机生成,并且不限个数。

支持真分数:需要用到生成分子、分母的函数,将分数化简等。

统计正确率:需要设置一个计算变量,并需要用一个判断正确的函数。

二、设计思路

首先根据需求分析,进行大体的设计:

生成题目→输入答案→判断正误→下一道题→生成题目→ ......→显示正确率

我和搭档决定一共用四个类,来完成本次项目:1.Main.java   2.栈.java  3.基本运算计算.java  4.栈内运算.java

UML类图:

三、关键代码

压栈\出栈:

第一周我们打算先完成栈和计算的部分,根据老师发的参考网站,我们又自行百度了很多关于栈的学习资料...但由于我们的水平有限,经过一下午的时间,还是未能完全搞懂如何利用栈来进行后缀计算,所以我们向学长请教,在学长的指导下,完成了部分代码。我们的栈主要分为两个部分,一是DataStack,专门用来存储数字,二是CharStack用来存储运算符。

public class CharStack {
int n;
char [] a;
int top = -1;
public CharStack(int m) { //定义栈的大小
this.n=m;
}
void getStack() { // 定义栈的大小
a = new char[n];
}
void push(char data) { //压栈
a[++top]=data;
}
char pop() {//出栈
return a[top--];
} }

  

public class DataStack { //代码原理同上一个CharStack
int n;
Rational [] a;
int top = -1;
public DataStack(int m) {
this.n=m;
}
void getStack() {
a = new Rational[n];
for(int i=0;i<n;i++) {
a[i] = new Rational();
}
}
void push(Rational data) {
top++;
a[top].numerator=data.numerator;
a[top].denominator=data.denominator;
}
Rational pop() {
return a[top--];
}
}

  

题目运算:

而计算部分我们则采取了全分数计算的方式,整数也作为分母为1的分数。并且还能做到对分数进行约分,我们想的是利用找分子分母最大公约数,然后同除以其约数,完成约分。在将运算共分为四种情况:加减乘除。先利用分子分母有理化,将分母化为一样的,然后再进行基本运算,得到新的分数,再进行约分,得到答案。

   void setNumerator(double a) {  //设置分子
double c=f(Math.abs(a),denominator); //计算最大公约数
numerator = a/c;//约分
denominator = denominator/c;
if(numerator<0&&denominator<0) { //分子分母负数情况
numerator = -numerator;
denominator = -denominator;
}
}
void setDenominator(double b) { //设置分母
double c=f(numerator,Math.abs(b)); //计算最大公约数
numerator = numerator/c;
denominator = b/c;
if(numerator<0&&denominator<0) {
numerator = -numerator;
denominator = -denominator;
}
}
double getNumerator() {//返回分子
return numerator;
}
double getDenominator() {
return denominator;
}
double f(double a,double b) { //求a和b的最大公约数
if(a==0) return 1;
if(a<b) {
double c=a;
a=b;
b=c;
}
double r=a%b;
while(r!=0) { //辗转相除
a=b;
b=r;
r=a%b;
}
return b;
}

栈内运算:

这一部分我们主要思路是:将生成的运算表达式的字符串转换为double型然后进行调用题目运算的部分进行栈内运算,并且将具体的数字压栈出栈运算都放在了这里进行。这一部分主要参考与博客《调度场的运算》:http://hczhcz.github.io/2014/02/27/shunting-yard-algorithm.htm。虽然说完成这个功能的代码比较繁琐,但是最终还是能够达到预期效果。

	Rational manage() {
int i=0;
Rational r = new Rational();
double d;
while(true) {
if(i>=a.length())
break;
char c = a.charAt(i); //看第i处的内容
if(c>='0' && c<='9') {//从字符串中检测数字
String temp = String.valueOf(c);
String s = new String();
s = s+temp;
i++;
if(i>=a.length()) {
d = Double.parseDouble(s); //将字符串转换为double型
r.setNumerator(d);
datastack.push(r);
break;
}
c = a.charAt(i);
while(c>='0' && c<='9') {
temp = String.valueOf(c);
s = s+temp;
i++;
if(i>=a.length())
break;
c = a.charAt(i);
}
d = Double.parseDouble(s);
r.setNumerator(d);
datastack.push(r);
continue;
}
else if(c=='*' || c=='/') {//从字符串中检测运算符
while(true) {
if(charstack.top==-1) {//如果符号栈顶无元素,入栈。
charstack.push(c);
break;
}
if(charstack.a[charstack.top]=='+' || charstack.a[charstack.top]=='-') {//如果符号栈顶是+或-,入栈。
charstack.push(c);
break;
}
else if((charstack.a[charstack.top]=='*' || charstack.a[charstack.top]=='/') && (datastack.top>=1)) {//如果符号栈顶是*或/,并且栈内元素大于等于1,计算。
calculate(charstack.a[charstack.top]);
continue;
}
else {
charstack.push(c);
break;
}
}
}
else if(c=='+' || c=='-') {
while(true) {
if(charstack.top==-1) {//如果符号栈顶无元素,入栈。
charstack.push(c);
break;
}
else if((charstack.a[charstack.top]=='+' || charstack.a[charstack.top]=='-' || charstack.a[charstack.top]=='*' || charstack.a[charstack.top]=='/') && (datastack.top>=1)) {
calculate(charstack.a[charstack.top]);//计算。
continue;
}
else {
charstack.push(c);
break;
}
} }
else if(c=='(') {//如果符号是(,入栈。
charstack.push(c);
}
else if(c==')') {//如果符号是),栈内符号依次计算。
while(true) {
if(charstack.a[charstack.top]=='(') {
charstack.pop();
break;
}
else {
calculate(charstack.a[charstack.top]);
}
}
}
i++;
}
while(true) {
if(datastack.top>=1)
calculate(charstack.a[charstack.top]);
else
break;
}
return datastack.pop();
}

程序效果图:

四、遇到的困难及解决办法

问题1:不会栈的使用

问题1解决办法:参考网上的博客:《栈详解及Java实现》 https://www.cnblogs.com/fzz9/p/8167546.html,然后对于一些细节不懂的地方再请教学长

问题2:没有分数运算的思路,无从下手

问题2解决办法:参考网上的博客:《Java-分数运算》https://blog.csdn.net/slyslyme/article/details/80032526。

五、对小伙伴鑫浩的评价:

搭档是一个非常有责任心的伙伴,也是一个很热情的人,在我们开发项目之前,他就已经进行了一些关于项目所需函数的了解,并且在设计时他也非常积极,在共同工作时总能给与我很大的帮助。

六、P2P图

PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 20  20
· Estimate · 估计这个任务需要多少时间 30  30
Development 开发 300  200
· Analysis · 需求分析 (包括学习新技术) 300   350
· Design Spec · 生成设计文档 30   30
· Design Review · 设计复审 (和同事审核设计文档) 30   30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 30   30
· Design · 具体设计 180   90
· Coding · 具体编码 400  120
· Code Review · 代码复审 180  40
· Test · 测试(自我测试,修改代码,提交修改) 30  40 
Reporting 报告 90  60 
· Test Report · 测试报告 90   60
· Size Measurement · 计算工作量 90  20 
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 90  40 
  合计 1890 900 

20175126Apollo 20175126《Java程序设计》结队编程项目——四则运算的更多相关文章

  1. 20175324王陈峤宇 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结

    20175324王陈峤宇 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 这次的结对作业是要求我们利用栈来设计一个计算器. 自动生成四则运算 ...

  2. 20175229许钰玮 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结

    20175229许钰玮 2018-2019-2<Java程序设计>结对编程项目-四则运算 第一周 阶段性总结 需求分析 自动生成四则运算题目(加.减.乘.除). 既可以用前缀算法(波兰算法 ...

  3. 20175311胡济栋 2018-2019-2《Java程序设计》结对编程项目-四则运算 第二周 阶段性总结

    20175311胡济栋 2018-2019-2<Java程序设计>结对编程项目-四则运算 第二周 阶段性总结 需求分析 这是利用栈来设计一个计算器的第二阶段总结. 自动生成四则运算的题目( ...

  4. 2018-2019-2 《Java程序设计》结对项目阶段总结《四则运算——整数》(二)

    20175218 2018-2019-2 <Java程序设计>结对项目阶段总结<四则运算--整数> 一.需求分析 实现一个命令行程序,要求: 自动生成小学四则运算题目(加,减, ...

  5. # 2019-2020-4 《Java 程序设计》结对项目总结

    2019-2020-4 <Java 程序设计>结对项目阶段总结---<四则运算--整数> 一.需求分析 实现一个命令行程序 要求: 自动生成小学四则运算题目(加,减,乘,除): ...

  6. 结对编程项目——四则运算vs版

    结对编程项目--四则运算vs版 1)小伙伴信息:        学号:130201238 赵莹        博客地址:点我进入 小伙伴的博客 2)实现的功能: 实现带有用户界面的四则运算:将原只能在 ...

  7. 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结

    码云链接 https://gitee.com/A5320/pair_programming_code 需求分析 实现一个命令行程序,要求: 1.自动生成小学四则运算题目(加.减.乘.除) 2.支持整数 ...

  8. 20175316盛茂淞 2018-2019-2《Java程序设计》结对编程项目-四则运算 第二周(6)

    20175316与20175329 结对编程练习_四则运算(第二周) 1.需求分析 实现一个命令行程序,要求: 自动生成指定数量的小学四则运算题目(加.减.乘.除) 支持整数 统计正确率 支持多运算符 ...

  9. 使用Java实现数据库编程 项目(宠物商店)

    创建数据库代码: DROP DATABASE IF EXISTS petShop; CREATE DATABASE petShop; USE petShop; /*创建表*/ CREATE TABLE ...

随机推荐

  1. 7.2.4 else与if配对

    规则是,如果没有花括号,else与离它最近的if匹配,除非最近的if被花括号括起来. 注意:要缩进"语句","语句"可以是一条简单语句或复合语句. 记住,编译器 ...

  2. excle删除重复项的行,自定义删除第几个

    在B1输入 =COUNTIF(A$1:A1,A1) 下拉,会有数字1.2.1.2 第二步,选中B列升序排序,排序后,将B列为1的整行删除即可. 再补充下,这样是以姓名为条件来筛选,不会影响你的数据.你 ...

  3. C#和.Net的关系

    1..net(dot net) .net是一个平台,抽象的平台概念. 实现形式是库:①定义了基本的类型(通用类型系统CTS,common type system).   ②包含.net公共语言运行库( ...

  4. 【原创】Open JDK更换过程及更换后的问题总结与分析

    由于2019年1月起Oracle对通用计算以外的应用场景开始收费,综合看来还是主要针对嵌入式的Java应用进行收费,毕竟嵌入式设备的数量是庞大的,可以有数亿元进账. 因Oracle JDK收费,各大公 ...

  5. Angular CLI: 全局脚本

    全局脚本 有的时候,我们需要加载全局脚本,例如 jQuery 脚本库,第三方的控件库等等.比如 jQuery 可以直接加载到 window 对象上,这就需要我们使用 Angular 中的全局脚本来处理 ...

  6. koa-passport实现本地验证

    安装 yarn add koa-passport passport-local 先看下passport.js登录策略,判断用户和密码 const passport = require('koa-pas ...

  7. Nginx——基本操作

    1.获得root用户权限 如果鉴定失败多试几次 一. gcc 安装安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装: yum install ...

  8. python类特列方法使用

    class Rgc(object): def __new__(cls, *args, **kwargs): print('在类通过__new__方法实例化一个对象') return super(Rgc ...

  9. 快速获取IP地址的各种方法

    调用百度的IP定位API(首先需要去百度开放平台注册申请key值http://lbsyun.baidu.com/apiconsole/key) http://api.map.baidu.com/loc ...

  10. Anatomy of a Database System学习笔记 - 查询

    查询解析 解析会生成一个查询的内部展示.格式检查包含在解析过程中. 每次解析一个SELECT,步骤如下:1. 从FROM里找到表名,转换成schema.tablename.这一步需要调用目录管理器ca ...