源码在Github的仓库主页链接地址:https://github.com/rucr9/rucr

  看到这个题目,大概很多人会发出“切,这也太简单了吧!有必要小题大做?”的感叹!是的,仅仅作为一道数学运算是没难度,但是,如何实现智能出题并计算正确答案,为大脑减压呢?接下来,我将用java编写程序实现小学四则运算。

 需求分析

  1.程序可接收一个输入参数n,然后随机产生n道加减乘除练习题;

  2.每个数字在 0 和 100 之间,运算符在3个到5个之间;

  3.所出的练习题在运算过程中不得出现负数与非整数;

  4.将练习题和计算结果一起输出到文件中;

  5.当程序接收的参数为4时,以下为输出文件示例:

  

功能设计

  用户输入需要出题的数量n,然后随机产生n道加减乘除练习题,每个数字在 0 和 100 之间,运算符在3个到5个之间,并且所出的练习题在运算过程中不得出现负数与非整数;最后将练习题和运算结果输出到result.txt文件中。

设计实现

  1.类

  主类:Arithmetic,这个类主要是用户输入出题的数量,随机产生练习题,并调用Expression类中的方法计算结果,最后输出到result.txt文件中。

  运算类:Calculate,此类规定了运算符的优先级和计算规则。

  逆波兰式转换类:Expression,此类负责将中序表达式转换为右序表达式,并调用Calculate中的方法求值。

  栈类:Stack,此类定义栈方法。

  2.程序执行流程

测试运行

                                             

核心代码

  Arithmetic类

 public static ArrayList<String> ss = new ArrayList<String>();

     public static void main(String[] args) throws Exception {

             System.out.println("Input a number:");
int count = new Scanner(System.in).nextInt();
File file =new File("./result.txt");
FileOutputStream fops=null ; try {
fops = new FileOutputStream(file); } catch (FileNotFoundException e) {
e.printStackTrace();
}
PrintStream ps= new PrintStream(fops);
ps.println("201571030125");
boolean f = true;
for (int i=0;i<count;i++) {
String data = Data();
String input = data;
ss.add(input);
if (input.equals("q"))
break;
else {
Expression express = new Expression(input);
f = express.getResult();
if(!f) i--;
else ps.println(data + "=" + express.getExpresult());
}
}
} //随机产生算式
public static String Data()
{
Random rand =new Random();
ArrayList<Integer> numlist = new ArrayList<Integer>();
ArrayList<String> express = new ArrayList<String>();
//产生随机数
for(int i=0;i<5;i++)
{
numlist.add(rand.nextInt(100)+1);
}
//System.out.print(numlist);
String[] operator=new String[]{"+","-","*","/"};
int size=numlist.size();
String[] num=new String[size];
for(int i=0;i<numlist.size();i++){
num[i]=String.valueOf(numlist.get(i));
}
String exp="";
for(int j=0;j<num.length;j++)
{
express.add(num[j]);
express.add(operator[rand.nextInt(4)]);
}
//System.out.print(express); for(int i=0;i<express.size()-1;i++)
exp+=express.get(i);
return exp;
}

  Calulate类

 // 判断是否为操作符号
public static boolean isOperator(String operator) {
if (operator.equals("+") || operator.equals("-")
|| operator.equals("*") || operator.equals("/")
|| operator.equals("(") || operator.equals(")"))
return true;
else
return false;
}
// 设置操作符号的优先级别
public static int priority(String operator) {
if (operator.equals("+") || operator.equals("-"))
return 1;
else if (operator.equals("*") || operator.equals("/"))
return 2;
else
return 0;
}
// 做2值之间的计算
public static String twoResult(String operator, String a, String b) {
try {
String op = operator;
String rs = new String();
double x = Double.parseDouble(b);
double y = Double.parseDouble(a);
boolean f = true; double z = 0.0;
if (op.equals("+"))
z = x + y;
else if (op.equals("-"))
z = x - y;
else if (op.equals("*"))
z = x * y;
else if (op.equals("/"))
{
if(y==0) {
y=1;
z=999999;
}
z = x / y;
if(z*y!=x) z=999999;
}
else
z = 999999;
if(z<0) z=999999;
if(z!=(int)z) z=999999;
return String.valueOf(z);
} catch (NumberFormatException e) {
System.out.println("input has something wrong!");
return "Error";
}
}

  逆波兰式转换方法

  private void toRight() {
Stack aStack = new Stack();
String operator;
int position = 0;
while (true) {
if (Calculate.isOperator((String) expression.get(position))) {
if (aStack.top == -1
|| ((String) expression.get(position)).equals("(")) {
aStack.push(expression.get(position));
} else {
if (((String) expression.get(position)).equals(")")) {
while(true){
if (aStack.top != -1&&!((String) aStack.top()).equals("(")) {
operator = (String) aStack.pop();
right.add(operator);
}else{
if(aStack.top != -1)
aStack.pop();
break;
}
}
} else {
while(true){
if (aStack.top != -1&& Calculate.priority((String) expression
.get(position)) <= Calculate
.priority((String) aStack.top())
) {
operator = (String) aStack.pop();
if (!operator.equals("("))
right.add(operator);
}else{
break;
} }
aStack.push(expression.get(position));
}
}
} else
right.add(expression.get(position));
position++;
if (position >= expression.size())
break;
}
while (aStack.top != -1) {
operator = (String) aStack.pop();
if(!operator.equals("("))
right.add(operator);
}
}

  逆波兰式求值方法

 boolean getResult() {

         this.toRight();

         Stack aStack = new Stack();
String op1, op2, is = null;
String temp="";
Iterator it = right.iterator();
while (it.hasNext()) {
is = (String) it.next();
if (Calculate.isOperator(is)) {
op1 = (String) aStack.pop();
op2 = (String) aStack.pop();
temp = Calculate.twoResult(is, op1, op2);
double td = Double.parseDouble(temp.trim());
if(td==999999.0){
return false; }
aStack.push(temp);
} else
aStack.push(is);
}
expresult = (String) aStack.pop(); it = expression.iterator();
while (it.hasNext()) {
String tempstr = (String) it.next();
System.out.print(tempstr); }
System.out.println("=" + expresult);
return true; }

总结

  此项目看似简单,但实际上要考虑的问题有很多,比如如何产生随机数,随机数和运算符如何结合,用什么结构存储数据,使用什么方法计算表达式(正则表达式,逆波兰式等等),如何去除不符合要求的运算式,如何处理异常等等。

  起初看到题目时,感觉这不就是加减乘除运算嘛,有什么难的。但是,当具体设计的时候发现困难重重,必须思路清晰,逻辑缜密,写代码时才不会东一下西一下,最后一团乱,连自己都搞不明白自己在干嘛了,所以,拿到任何一个题目时都不要急于写代码,做好需求分析、设计实现等前期工作是非常重要的。

  最后,提醒各位园友养成编辑过程中随时保存博客的习惯,以防手一抖、头脑一发昏刷新网页或者关闭浏览器,这可真的是前功尽弃啊!痛到欲哭无泪。。。本人就是犯了这样的错误,导致重写博客!!!

存在的问题

  1.最后的计算结果都带有小数点;

  2.java自带了栈类,我在这里重新定义有些多余;

  3.产生的练习题都是5个运算数。

  本项目参考逆波兰式算法http://blog.csdn.net/yunxiang/article/details/1918717,并根据需求和自己的理解进行改进而成,如有好的建议,请多多指教!我将非常感谢!

PSP

PSP2.1 任务内容 计划完成需要的时间(min) 实际完成需要的时间(min)
Planning 计划  15  20
Estimate  估计这个任务需要多少时间,并规划大致工作步骤   20  25
Development 开发  120 180
Analysis  需求分析 (包括学习新技术) 15  10
Design Spec 生成设计文档   10  8
Design Review  设计复审 (和同事审核设计文档)   15 20
Coding Standard 代码规范 (为目前的开发制定合适的规范)   20  25
Design 具体设计  30 35
Coding 具体编码  180  240
Code Review 代码复审  15  20
Test 测试(自我测试,修改代码,提交修改)  20  25
Reporting 报告  20  22
Test Report 测试报告  5  5
Size Measurement 计算工作量  5  10
Postmortem & Process Improvement Plan 事后总结 ,并提出过程改进计划  8  10

小学四则运算练习(JAVA编写)的更多相关文章

  1. 作业四:个人项目-小学四则运算之JAVA版

    作业的要求来自于:https://edu.cnblogs.com/campus/gzcc/GZCC-16SE2/homework/2186 代码所在的github远程仓库的地址:https://git ...

  2. 作业二:个人编程项目——编写一个能自动生成小学四则运算题目的程序

    1. 编写一个能自动生成小学四则运算题目的程序.(10分)   基本要求: 除了整数以外,还能支持真分数的四则运算. 对实现的功能进行描述,并且对实现结果要求截图.   本题发一篇随笔,内容包括: 题 ...

  3. java实现自动生成小学四则运算——朱庭震,詹祺豪

    组员:朱庭震,詹祺豪 Github地址:https://github.com/ztz1998/second/tree/master 1题目:实现一个自动生成小学四则运算题目的命令行程序. 2说明: 自 ...

  4. 300道随机四则运算小程序(java编写)

    这是由Java编写的300道随机四则运算小程序, 运算数范围为0~100(不包括100),运算结果保留两位小数. 程序代码: import java.util.*; class Yunsuan{ pu ...

  5. 结对编程--四则运算(Java)萧英杰 夏浚杰

    结对编程--四则运算(Java)萧英杰 夏浚杰 Github项目地址 功能要求 题目:实现一个自动生成小学四则运算题目的命令行程序 使用 -n 参数控制生成题目的个数(实现) 使用 -r 参数控制题目 ...

  6. 结对编程-四则运算生成器(java实现)

     结对伙伴:陈振华  项目要求 1.题目:实现一个自动生成小学四则运算题目的命令行程序. 2.需求: 1. 使用 -n 参数控制生成题目的个数 2. 使用 -r 参数控制题目中数值(自然数.真分数和真 ...

  7. 结对编程 四则运算(java)(胡大华 黄绪明)

    Github项目地址 https://github.com/yogurt1998/Myapp 项目需求 题目: 实现一个自动生成小学四则运算题目的命令行程序 功能 1.使用-n 参数控制生成题目的个数 ...

  8. myapp——自动生成小学四则运算题目的命令行程序(侯国鑫 谢嘉帆)

    1.Github项目地址 https://github.com/baiyexing/myapp.git 2.功能要求 题目:实现一个自动生成小学四则运算题目的命令行程序 功能(已全部实现) 使用 -n ...

  9. 小学四则运算APP 最后阶段

    团队成员:陈淑筠.杨家安.陈曦 团队选题:小学四则运算APP 这次发布的是我们APP的最终版本!图片背景有根据用户需求改变!还增加了草稿纸运算的画布功能! 运行结果如下: package com.ex ...

随机推荐

  1. 2017-2018-2 20155315《网络对抗技术》Exp4:恶意代码分析

    实验目的 是监控你自己系统的运行状态,看有没有可疑的程序在运行. 是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生指令或sysinternals,systracer套件 ...

  2. 20145209刘一阳《JAVA程序设计》第九周课堂测试

    第九周课堂测试 1.域名解析服务器(ARP)负责将域名转化为IP地址,从而与主机连接.(B) A .true B .false 2.下列关于URL类的说法,正确的是(BD) A .URL 类自身可根据 ...

  3. jQuery学习-页面就绪函数

    1.开发工具HBuilder <!DOCTYPE html> <html> <head> <meta charset="utf-8" /& ...

  4. 3992: [SDOI2015]序列统计

    3992: [SDOI2015]序列统计 链接 分析: 给定一个集和s,求多少个长度为n的序列,满足序列中每个数都属于s,并且所有数的乘积模m等于x. 设$f=\sum\limits_{i=0}^{n ...

  5. 牛客练习赛31 D 最小相似度

    最小相似度 链接 分析: 转化为求1的个数,这样两个串不同的位置的个数就是1的个数.那么对于一个二进制串x,它的贡献就是max{x与s[i]异或后0的个数}=>max{m-x与s[i]异或后1的 ...

  6. Java Swing:JPanel中添加JPanel

    1. JPanel默认布局是FlowLayout,如果不设置父JPanel的布局,则子JPanel自动填满父JPanel. JPanel jpanel = new JPanel(); jpanel.s ...

  7. 一个java程序员该具备的工具

    http://itindex.net/detail/37115-java-%E7%A8%8B%E5%BA%8F%E5%91%98-%E5%B7%A5%E5%85%B7 文章很详细.

  8. [BZOJ4028][HAOI2015]公约数数列[分块+分析暴力]

    题意 题目链接 分析 首先明确 \(xor\) 运算和 \(\rm gcd\) 没有联系! 注意到一个数字取 \(\rm gcd\) 且保证每次取 \(\rm gcd\) 值都会变小的话,最多取 \( ...

  9. Laravel 跨框架队列交互

    公司大部分项目是laravel框架,但有些是yii框架,这两个框架之间有消息需要通信,比如在yii框架发布消息,laravel框架中的队列去处理,用redis作为消息连接纽带 laravel 队列原理 ...

  10. [VB.NET][C#]调用API获取或设置键盘按键状态

    前言 通过 C# 或 VB.NET,你只需编写少量的代码即可实现一个按键精灵. 第一节 接口 调用系统 API 实现获取或设置指定的按键状态. 获取按键状态 调用 GetAsyncKeyState() ...