GIT地址 点一下
GIT用户名 Mretron
学号后五位 62517
博客地址 点一下
作业链接 点一下

在征得陈老师的同意下,使用java面向对象语言+IDEA工具完成本次作业

一、前期配置

虽然说VS是宇宙最好的集成开发编程软件,但是咱们的IDEA也不是等闲之辈,她的美丽唯有心人耐心发现,方能觉察此番美景。

话不多说,咱么直接一探究竟。

首先官网下载好IDEA,以及Git。

以及准备好自己github的项目(我已经在助教的github上fork到自己的账号了)

打开IDEA。

请注意,咱们现在需要去配置Git->然后克隆项目到本地。

IDEA面板中->File->Setting->Version Control -> Git->如图配置

现在咱们已经配置了git,那么现在就开始clone一个项目到本地,进行开发

File->Project from version Control... -> Git

输入你想要克隆的项目URL->点击Clone即可等待完成

克隆完成后,在当前文件夹下创建一个module项目,即可开始在ertron/src文件夹下编写代码:

二、编写代码

在完成了上述配置任务过后,即可开始愉悦地编码了。

咱们先来看看题目:

阿超家里的孩子上小学一年级了,这个暑假老师给家长们布置了一个作业:家长每天要给孩子出一些合理的,但要有些难度的四则运算题目,并且家长要对孩子的作业打分记录。

作为程序员的阿超心想,既然每天都需要出题,那何不做一个可以自动生成小学四则运算题目与解决题目的命令行 “软件”呢。他把老师的话翻译一下,就形成了这个软件的需求:

  • 程序接收一个命令行参数 n,然后随机产生 n 道加减乘除(分别使用符号+-*/来表示)练习题,每个数字在 0100 之间,运算符在 2 个 到 3 个之间。
  • 由于阿超的孩子才上一年级,并不知道分数。所以软件所出的练习题在运算过程中不得出现非整数,比如不能出现 3÷5+2=2.6 这样的算式。
  • 练习题生成好后,将生成的 n 道练习题及其对应的正确答案输出到一个文件 subject.txt 中。
  • 当程序接收的参数为4时,以下为一个输出文件示例。

13+17-1=29

11*15-5=160

3+10+4-16=1

15÷5+3-2=4

我的思路:

既然是随机生成式子,再利用题目的一些规则(不能有分数,运算符在2个到3个之间,数字在0和100之间),可以借鉴后续表达式以及简化版的逆波兰算法(利用两个栈分别存储数字,和运算符,进行及时计算)。

编写代码:

创建了两个类CalculatorMachine和CantCalculateException

  • 类CalculatorMachine:计算机机器类,提供一些方法产生符合题目的式子
  • CantCalculateException:自定义异常类,如果遇到不符合题目的计算(出现了分数,或者除以0),则抛出自定义的这个异常,进行重新生成式子,直到符合题意

CalculatorMachine.java中的私有属性,详情作用请看注释:

    /**
* 用于存储生成的题目,使用Set集合数据结构使得题目不会产生重复
*/
private HashSet<String> problem = new HashSet<>(); /**
* 用于存储数字的栈
*/
private Stack<Integer> numbers = new Stack<>(); /**
* 用于存储符号的栈
*/
private Stack<Integer> operators = new Stack<>(); /**
* 用与生成随机数
* random.nextInt(20) :即可得到20以内不包含20的随机数
*/
private Random random = new Random();

public void getAll()方法:调用其他方法

    /**
* 传入num题目数目
* 即可将题目写入到subject.txt文件中
* @param num 代表需要的题目数量
* @return 没有任何问题,即返回true代表生成成功
*/
public void getAll(int num){ // 循环得到式子直到满足数目
while(problem.size() < num) {
getOne();
}
if(writeToFile()) {
System.out.println("已经根据你的要求生成" + num + "个式子!");
} }

public void getOne()方法:生成一个符合要求的算式并且后续表达式得到结果

    /**
* 用于生成一个符合要求的算式
* 使用后续表达式得到结果
*/
public void getOne() { // 用来保存生成的当前式子
String result = ""; // 运算符的个数为 2 或者 3 个
int operator_count = random.nextInt(2)+2; //数字的个数,根据题意,两个符号,则代表3个计算数,三个符号,则代表4个计算数
int num_count = operator_count == 2 ? 3: 4; // 根据后续表达式就搞定了两个栈的东西 61+47*96=4573
for(int i = 0; i < operator_count + num_count ; i++) {
// 如果是偶数,则代表着数数字
if(i%2==0) {
// 在数字栈中存入一个范围内的随机数
numbers.push(random.nextInt(101));
// 进行符号保存
result += numbers.peek();
// 如果是奇数,则代表着符号位
} else if(i%2!=0) {
// 1:+ , 2:- , 3:* 4:/
int opertor = random.nextInt(4) + 1;
// 如果遇到+ - 准备入栈顶为 * /的话,需要进行计算
while(!operators.empty() && opertor <=2 && operators.peek() >=3) {
result = calculateUtil(result);
}
// 这个符号符合当前栈的规则,则入栈
operators.push(opertor);
// 记录这个符号
if(operators.peek()==1) {
result += '+';
} else if(operators.peek() == 2){
result += '-';
} else if(operators.peek() == 3){
result += '*';
} else if(operators.peek() == 4){
result += '÷';
}
}
} // 根据剩余的栈计算最后的值
while(!operators.empty()) {
result = calculateUtil(result);
}
// 如果最后的计算结果为负数,直接返回,放弃此次的式子
if(numbers.peek()<0){
return;
}
// 最后加上等于符号
result += '=';
// 走到这一步,说明这个式子没有问题,符合题意
// 所以放入到set集合中
problem.add(result+=numbers.pop());
}

private int calculator(int a, int b, int operator):根据符号计算

 /**
* 根据符号计算
*/
private int calculator(int a, int b, int operator) throws ArithmeticException, CantCalculateException { if(operator == 1) {
return a+b;
} else if(operator == 2) {
return a-b;
} else if(operator == 3) {
return a*b;
} else if(operator == 4) {
// 如果不能整除,则抛出我们自定义的Exception
if(a<b || a%b != 0) {
throw new CantCalculateException();
}
return a/b;
}
return 0;
}

private String calculateUtil(String result)方法:进行后续表达式特殊计算

    /**
* 进行后续表达式特殊计算
* + - 入栈顶为 * / 的情况
* 除法带有分数的情况
* @param result
* @return
*/
private String calculateUtil(String result){ int a = numbers.pop();
int b = numbers.pop(); try {
int this_operator = operators.pop();
if(!operators.isEmpty() && this_operator==2 && operators.peek()==2) {
numbers.push(calculator(b,a,1));
}else if (!operators.isEmpty() && this_operator==4 && operators.peek()==4) {
numbers.push(calculator(b,a,3));
}
else {
numbers.push(calculator(b,a,this_operator));
} } catch (CantCalculateException e) { int pr_b = b;
a = random.nextInt(101);
b = random.nextInt(101);
// a除数不能为0,满足b能够整除a,满足b>a
while (a == 0 || b % a != 0 || b < a || b > 100) {
a = random.nextInt(101);
b = random.nextInt(101) + a;
}
numbers.push(b);
numbers.push(a);
operators.push(4);
result = result.substring(0, result.indexOf(pr_b + ""));
result += b;
result += '÷';
result += a;
}
return result; }

private boolean writeToFile():将生成的所有式子写入到subject.txt

    /**
* 将生成的所有式子写入到subject.txt
* @return
*/
private boolean writeToFile() {
File file = new File("subject.txt");
try{
if(!file.exists()) {
file.createNewFile();
}
FileWriter fileWriter = new FileWriter(file.getAbsoluteFile());
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
for(String s : problem) {
bufferedWriter.write(s);
bufferedWriter.newLine();
}
bufferedWriter.close();
} catch (Exception e) {
e.printStackTrace();
}
return true;
}

三、单元测试与回归测试

对于java来说有专门的junit单元测试包,非常方便进行单元测试。

第一步:在需要测试类中Ctrl+Alt+T出现单元测试提示框 -> Create New Test...

第二步:在测试类中调用需要测试的类的方法

第三步:运行测试类,查看测试结果,是否成功

测试完成,上述程序符合题目要求且成功运行

四、调试

单步调试有利于实时看到每一步的代码中变量的值变化。

非常适合用于排错。

五、性能测试

JProfiler是用于分析J2EE软件性能瓶颈并能准确定位到Java类或者方法有效解决性能问题的主流工具,它通常需要与性能测试工具如:LoadRunner配合使用,因为往往只有当系统处于压力状态下才能反映出性能问题。

所以我采用JProfiler进行性能测试。

下载安装JProfiler过后需要在IDEA进行配置,首先File->Setting->Plugins搜索下载JProfiler插件

安装完插件过后,配置JProfiler的启动程序的地址。

配置完毕即可点击左边的JProfiler启动检测

提交代码至源库

首先Commit提交修改的代码到本地仓库

Commit过后push到自己的github账号上面

登录自己的github账号去检查是否push成功

提交到源库

总结:

其实在之前就用过git进行push自己的项目至网站。但是并没有版本控制的意识,只是当做代码仓库罢了。

得益于此次git课程的学习,算是对了一个项目如何利用git协同协作,提交自己的更新代码至源库,对以后的项目管理更为深刻。

想提一下自己完成的这个程序算法,借用了后续表达式,逆波兰算法,后续表达式可以使得计算机更为方便地计算数据,当然实现来说可能会难一点。在完成这个算法的过程中,为了满足题意:不能出现分数,我自己还主观地认为一年级的朋友应该不会负数,所以自己增加了这样的限定。

最后,完成过后,觉得自己的一些编程习惯还是需要改变,比如有些代码太过于重复,进行提炼为一个方法,增加代码的可重用性,使得代码更为简洁。所以,可能整个程序的代码看起来就是一会儿调用另一个方法。

既然有这样的不断调用其他方法的结构,那么代码中的注释一定不能少。自己也在学着写标准的注释结构。使得阅读代码起来更符合规范,且方便。

  • 比如,类上面的注释使用/**

  • 方法内部的注释使用双斜杠,并且内容需要与符号空一格

还需要学习的东西很多,但是在课程的帮助下也算踏实

《构建之法》个人第二次作业之git学习的更多相关文章

  1. 熟悉GitHub、VS工具的使用(《构建之法》第二次作业)

    GIT地址 https://github.com/slothph GIT用户名 slothph 学号后五位    62323 博客地址 https://www.cnblogs.com/slothph/ ...

  2. JAVA第二次作业展示与学习心得

    JAVA第二次作业展示与学习心得 在这一次作业中,我学习了复选框,密码框两种新的组件,并通过一个邮箱登录界面将两种组件运用了起来.具体的使用方法和其他得组件并没有什么大的不同. 另外我通过查阅资料使用 ...

  3. 构建之法助教园地第一次作业--点评<西北师范大学|李晓婷>

    一 博客点评 第一次作业--准备篇:https://www.cnblogs.com/Mookiepiece/p/10464606.html#4192515 点评内容: 首先,你对电脑很感兴趣,兴趣就是 ...

  4. 2015-2016-1 学期《软件工程》学生名单-- PS:教材使用《构建之法》第二版 --邹欣著

    1208053044 王威 男 1313023001 饶阳梅 女 1313023002 应蕾蕾 女 1313023004 袁立萍 女 1313023005 黎洋阳 女 1313023006 蒋欣 女 ...

  5. 第二次作业-熟悉git

    GIT地址 https://github.com/gentlemanzq/yunsuanhomework GIT用户名  gentlemanzq 学号后五位  62320 博客地址 https://w ...

  6. 第二次作业:Git的安装与使用

    ---恢复内容开始--- 本次作业要求来自:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE1/homework/2103 1.首先安装git bash软件, ...

  7. 软件工程(GZSD2015)第二次作业文档模板

    题目: (此处列出题目) 需求分析: 基本功能 基本功能点1 基本功能点2 ... 扩展功能(可选) 高级功能(可选) 设计 设计点1 设计点2 ... 代码实现 // code here 程序截图 ...

  8. <<构建之法>>略读感想

    经过对构建之法这本书的快速阅读和学习,我有以下疑问. 1.对软件工程来说是应该更注重结果和功能的实现还是更注重代码的易读和完整? 2.应该怎样平衡不同用户的不同需求以达到使大多数人满意的目的? 3.应 ...

  9. 软件工程(GZSD2015) 第二次作业文档模板

    题目: (此处列出题目) 需求分析: 基本功能 基本功能点1 基本功能点2 ... 扩展功能(可选) 高级功能(可选) 设计 设计点1 设计点2 ... 代码实现 // code here 程序截图 ...

随机推荐

  1. Tplink路由器怎么设置无线桥接(转载)

    原始文章路径:http://www.pc6.com/video/8548.html .以下为转载内容(少量修改) 第1步 进入副路由器后台,选择网络参数,LAN口设置,把IP地址改成目标网络同一段的I ...

  2. Asp Core部署到IIS服务器

    之前有文章写了.Asp Core Kestrel服务器可以独立运行在linux下,也可以部署到Docker上面通过容器管理,当然也可以直接部署到IIS中 一:安装环境 1)首先需要在服务器安装对应环境 ...

  3. [转帖]Docker公司被收购,开源界尴尬不?

    Docker公司被收购,开源界尴尬不? https://news.51cto.com/art/201911/606189.htm Docker公司被谁收了? Docker公司被谁收了?Mirantis ...

  4. SQL IN 子查询返回多对值

    我们常用的IN 操作是这样的: select * from tab twhere t.col1 in ('value1''value2');12但是如果是多个列的取值来自同一个子查询呢? 我们是不是要 ...

  5. Word 插入目录详细教程 -- 视频教程(6)

    >> 视频教程链接:B站,速度快,清晰 更多关于插入目录的方法,参看:Word插入目录系列 未完 ...... 点击访问原文(进入后根据右侧标签,快速定位到本文)

  6. Vue框架(一)——Vue导读、Vue实例(挂载点el、数据data、过滤器filters)、Vue指令(文本指令v-text、事件指令v-on、属性指令v-bind、表单指令v-model)

    Vue导读 1.Vue框架 vue是可以独立完成前后端分离式web项目的js框架 三大主流框架之一:Angular.React.Vue vue:结合其他框架优点.轻量级.中文API.数据驱动.双向绑定 ...

  7. stvd使用中的一些问题

    1.stm8_interrupt_vector.c 会莫名其妙的自动出现,而且都是在项目目录下.进行如下操作 2.stvd编译时遇到no default placement for segment . ...

  8. Ubuntu 固定自己的IP

    使用以下命令 sudo vi /etc/network/interfaces 以下方文件内容进行覆盖 ​# interfaces(5) file used by ifup(8) and ifdown( ...

  9. golang 之 jwt-go

    主要针对jwt-go快速生成token.和如何取进行介绍,具体详情还请查看 github.com/dgrijalva/jwt-go 生成token package main import ( &quo ...

  10. git 学习笔记 --Bug分支

    软件开发中,bug就像家常便饭一样.有了bug就需要修复,在Git中,由于分支是如此的强大,所以,每个bug都可以通过一个新的临时分支来修复,修复后,合并分支,然后将临时分支删除. 当你接到一个修复一 ...