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

一、需求分析

实现一个命令行程序,要求:

  • 自动生成小学四则运算题目(加,减,乘,除)

    • 文本支持整数
    • 支持多运算符(例如生成包含n个运算符的题目)
    • 支持真分数(后续实现)
  • 统计正确率

扩展需求

  • 文件:

    • 处理生成题目并输出到文件
    • 完成题目后从文件读入并判断
  • 多语言支持:简体中文,繁體中文,English
  • 生成题目去重

二、设计思路以及代码解释

最开始看到这个结对项目的时候,我觉得,最为第一个项目,应该不会很难。而在真正看到项目的时候,也感觉不是很难。在这一点上,我和我的搭档是同一个想法,都觉得还行。但是越是往后做,就越发现,这怎么这么复杂...其实,是这样的,最开始,我们没有考虑到括号、运算优先级以及多个数字运算的问题,就只是简单设计了一个两个数字简单的四则运算,这个程序呢,我也发出来了,如下:

//生成随机整数的运算

public class Zheng {
int a=0,b=0,c=0;
int result=0,g=0;
String s=null;
public void Zheng(){
a = (int)(Math.random()*100);//生成0-99的随机数
b = (int)(Math.random()*100);
c = (int)(Math.random()*4);//生成0-3的随机数,用来随机产生运算符
if(c==0){
System.out.println(a+"+"+b+"=");
result = a + b;
}
if(c==1){
System.out.println(a+"-"+b+"=");
result = a - b;
}
if(c==2){
System.out.println(a+"*"+b+"=");
result = a * b;
}
if(c==3){
if(b==0){
while(b==0)
b=(int)(Math.random()*10);//防止分母为0
}
else{
System.out.println(a+"/"+b+"=");
int smaller = a > b ? b : a;//将a与b中的最小值赋给变量
for (int i = 1; i <= smaller; i++) {
if (a % i == 0 && b % i == 0) {
g = i;
}//求a与b的最大公因子
}
a = a/g;
b = b/g;
s = a+"/"+b;
}
}
}
}

//实现四则运算

import java.util.*;
public class YunSuan {
public static void main (String args[]){
int x,z=0;
Zheng zheng = new Zheng();
System.out.print("请输入要生成的题目数:");
Scanner reader = new Scanner(System.in);
int n = reader.nextInt();
Random random = new Random();
for(int i=1;i<n+1;i++){
for(;;){
System.out.println("题目"+i+":");
zheng.Zheng();
System.out.print("请输入结果:");
if(zheng.c==3){
Scanner sc=new Scanner(System.in);
String s =new String();
s =sc.nextLine();
if(s.equals(zheng.s)){
z++;
System.out.println("此题正确");
}
else
System.out.println("此题错误,正确答案为:"+zheng.s);
}
else{
x =reader.nextInt();
if(x==zheng.result){
z++;
System.out.println("此题正确");
}
else
System.out.println("此题错误,正确答案为:"+zheng.result); }
break;
}
}
int o =(int)(((double)z/(double)n)*100);//计算正确率
System.out.print("完成"+n+"道题,正确数目为:"+z+",正确率为:");
System.out.printf("%d",o);
System.out.println("%");
}
}

四则运算简版链接:码云链接

而后来做的过程中,发现不仅仅是这么简单,我们需要考虑到很多东西,包括括号、运算优先级以及多个数字计算的因素等。于是我们卡在这里好长时间,特别是在做栈以及中缀转后缀这块时,我们不知道该如何做下去了。然后我们就查资料以及加上我们两个人的共同思考,终于知道了如何解决括号与计算问题,通过一段时间的努力,最终得出了代码。然而,依旧不是这么简单,我们的代码还是有一些问题,代码如下:

//生成随机数

import java.util.*;
public class RandomNum {
int RandomNum(int x){
int num =(int)(Math.random()*x);
return num;
}
} //生成随机运算符
import java.util.*;
public class RandomChar {
char RandomChar(){
int num = (int)(Math.random()*4);
switch (num){
case 0:return'+';
case 1:return'-';
case 2:return'*';
case 3:return'÷';
default:return 0;
}
}
}

//生成中缀表达式以及产生题目

import java.util.*;
public class Produce {
void Produce(int n){
RandomNum num = new RandomNum();
RandomChar c = new RandomChar();
Scanner reader = new Scanner(System.in);
String s = "";
String d = "";
String g = "";
String out = "";//最终的中缀表达式
String end = "";//转化后的后缀表达式
int count = 0;//记录做对的题目个数
for(int i=1;i<n+1;i++){
System.out.println("题目"+i+":");
int a = (int)(Math.random()*5+1);
int amount = num.RandomNum(a)+1;//记录随机产生运算符的个数
for(int j=0;j<amount;j++){
s = s+c.RandomChar()+" ";
}
String str[] = s.split(" ");//将字符串转化成字符串数组
for(int z=0;z<str.length;z++){
d = d+num.RandomNum(50)+str[z];
}
d = d + num.RandomNum(50);
switch((num.RandomNum(2))){
case 0:
System.out.println(d+" = ");//输出不带括号的中缀表达式
break;
case 1:
for(int k=0;k<str.length;k++){
g = num.RandomNum(50)+ str[num.RandomNum(str.length-1)] + "(" + num.RandomNum(50) + str[num.RandomNum(str.length-1)] + num.RandomNum(50) + ")" + str[k];
}//在中缀表达式中加入括号
g = g + num.RandomNum(50);
System.out.println(g+" = ");//输出不带括号的中缀表达式
break; }
out = g;
out = d;
int p = 0;//初始化最终得到的答案
infixToSuffix in = new infixToSuffix();
end = in.infixToSuffix(out);//将中缀表达式转化为后缀表达式
suffixToArithmetic ex = new suffixToArithmetic();
p = (int) ex.suffixToArithmetic(end);//计算后缀表达式的结果
System.out.print("请输入结果:");
int x = reader.nextInt();
if(x==p){
System.out.println("结果正确!");
count++;
}
else{
System.out.println("结果错误,正确结果是:"+p);
}
s="";
g="";
d="";
}
int result = (int)(((double)count/(double)n)*100);//计算正确率
System.out.println("总共答题"+n+"道,正确率为:"+result+"%");
} }

//将中缀表达式转化为后缀表达式

import java.util.*;
public class infixToSuffix {
public static String infixToSuffix(String infix) {
Stack<Character> stack = new Stack<Character>();
String suffix = "";
int length = infix.length();
for (int i = 0; i < length; i++) {
Character temp;
char c = infix.charAt(i);
switch (c) {
// 忽略空格
case ' ':
break;
// 碰到'(',push到栈
case '(':
stack.push(c);
break;
// 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
case '+':
case '-':
while (stack.size() != 0) {
temp = stack.pop();
if (temp == '(') {
stack.push('(');
break;
}
suffix += " " + temp;
}
stack.push(c);
suffix += " ";
break;
// 碰到'*''/',将栈中所有乘除运算符弹出,送到输出队列中
case '*':
case '/':
while (stack.size() != 0) {
temp = stack.pop();
if (temp == '(' || temp == '+' || temp == '-') {
stack.push(temp);
break;
} else {
suffix += " " + temp;
}
}
stack.push(c);
suffix += " ";
break;
// 碰到右括号,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号
case ')':
while (stack.size() != 0) {
temp = stack.pop();
if (temp == '(')
break;
else
suffix += " " + temp;
}
// suffix += " ";
break;
//如果是数字,直接送至输出序列
default:
suffix += c;
}
} //如果栈不为空,把剩余的运算符依次弹出,送至输出序列。
while (stack.size() != 0) {
suffix += " " + stack.pop();
}
return suffix;
}
}

//计算后缀表达式的值

import java.util.*;
public class suffixToArithmetic{
int suffixToArithmetic(String h) {
Stack<Integer>stack = new Stack<Integer>();
String b[] = h.split(" ");//将字符串转化为字符串数组
for(int i=0;i<b.length;i++){
String c = b[i];
if((c.equals("+")||c.equals("-"))||(c.equals("*")||c.equals("÷"))){
int y = stack.pop();
int x = stack.pop();
Caculate z = new Caculate();
stack.push(z.Caculate(x,y,c));//将运算结果重新压入栈
}//是运算符,弹出运算数,计算结果
else{
stack.push(Integer.valueOf(c));
}
}
return stack.pop();//弹出栈顶元素就是运算最终结果
}
}

//判定运算符并进行运算

class Caculate{
int Caculate(int x,int y,String c) {
if (c.equals("+"))
return x + y;
if (c.equals("-"))
return x - y;
if (c.equals("*"))
return x * y;
if (c.equals("/")){
if(x<=y||x==0) return 1;
else return x / y;
}
return 0;
}
}

四则运算链接:码云链接

三、总结分析与运行截图

结对项目总结与分析

我们开始的时候,都没有太注重这个项目,觉得它不难。但是在做起这个项目时,我们就发现自己错了————这个项目并不简单。相反,它还是很复杂的。这也让我们知道了为何它是结对项目了,而不是个人项目。在做这个项目的时候,我们遇到最大的问题就是缺少这一块的知识,所以我们不得不边学边做。因此,在编程中我们遇到了很多问题,包括往中缀表达式加入括号的问题,以及除法计算的问题,遇到左右括号数量不等的情况,遇到括号只括住一个数字或者一个运算符的问题,遇到遇见除法无法输出的问题,遇到无法计算出结果的问题。幸好,我的搭档非常厉害,这些大多数都是我的搭档张智敏解决的,但是依旧有个问题没有解决,就是除法计算问题:

(关于UML图,我们暂时还未弄好,在后面的结对项目中我们会补上)

代码运行截图

四则运算简版运行截图:



四则运算运行截图:

四、结对同伴的评价

在这次项目中,我的搭档张智敏同学是驾驶员的身份,而我是领航员的身份。在这次项目中,我的搭档充分体现了驾驶员的身份,所有代码都是他操控键盘打出来的。并且在遇到问题的时候,他都分析得很仔细认真,所以大多数问题都是他先想出解决办法并最后解决的,所以我认为我的搭档非常棒。在以后的项目中,我们会合作得更好,希望我能帮到我的搭档更多,争取把我们的项目做得更好。

五、代码托管

代码托管

2018-2019-2 《Java程序设计》结对项目阶段总结《四则运算——整数》(二)的更多相关文章

  1. 20172328 2018—2019《Java软件结构与数据结构》第二周学习总结

    20172328 2018-2019<Java软件结构与数据结构>第二周学习总结 概述 Generalization 本周学习了第三章集合概述--栈和第四章链式结构--栈.主要讨论了集合以 ...

  2. 2015-2016-2 《Java程序设计》项目小组博客

    2015-2016-2 <Java程序设计>项目小组博客 1451 完+美 java项目 守望先疯 JavaGroup 07_10_20_22 FromBottomToTop L.G.Su ...

  3. 结对项目作业报告——四则运算web项目

    成员:顾思宇2016011993 程羚2016012050   1.仓库地址:https://git.coding.net/DandelionClaw/WEB_Calculator.git 注: 本项 ...

  4. 20175234 《Java程序设计》第二周学习总结(二)

    学习内容总结 运算符与表达式 If语句.switch语句 break和continue语句 数组和for语句 IDEA的安装和调试 教材学习中的问题和解决过程 在第一次使用IDEA中出现了一些情况,在 ...

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

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

  6. 20165219 2017-2018-2《Java程序设计》课程总结

    20165219 2017-2018-2<Java程序设计>课程总结 一.每周作业链接汇总 20165219 我期望的师生关系 20165219学习基础与C语言基础调查 20165219 ...

  7. 20145330《Java程序设计》第二次实验报告

    20145330<Java程序设计>第二次实验报告 实验二 Java面向对象程序设计 实验内容 1.初步掌握单元测试和TDD 2.理解并掌握面向对象三要素:封装.继承多态 3.初步掌握UM ...

  8. 20155317 《Java程序设计》0510上课考试博客

    20155317 <Java程序设计>0510上课考试博客 二.Arrays和String单元测试 在IDEA中以TDD的方式对String类和Arrays类进行学习 测试相关方法的正常, ...

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

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

随机推荐

  1. 7.2.5 多层嵌套的if语句

    7.2.5 多层嵌套的if语句 在编写程序的代码之前要先规划好.首先,要总体设计一下程序. 为方便起见,程序应该使用一个连续的循环让用户能连续输入待测试的 数.这样,测试一个新的数字不必每次都要重新运 ...

  2. linux中的查找命令find,locate,which,whereis

    我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索.这些是从网上找到的资料,因为有时很长时间不会用到,当要用的时候经常弄混了.  which       查看可执行文 ...

  3. 正则表达式与Python中re模块的使用

    正则表达式与Python中re模块的使用 最近做了点爬虫,正则表达式使用的非常多,用Python做的话会用到re模块. 本文总结一下正则表达式与re模块的基础与使用. 另外,给大家介绍一个在线测试正则 ...

  4. [Notepad++]Notepad++怎么实现双视图/双窗口?

    作为windows下非常优秀的开源代码编辑器,Notepad++是工程师必备代码编辑器.相比较之下,老一辈文本编辑器如ultraedit,editplus,就显得繁琐.冗余.疲惫.我使用过Notepa ...

  5. YAML快速入门

    https://www.jianshu.com/p/97222440cd08 我们学习Java,都是先介绍properties文件,使用properties文件配合Properties对象能够很方便的 ...

  6. [STM32F103]PWM输入捕获配置

    l 初始化定时器和通道对应IO的时钟. l 初始化IO口,模式为输入: GPIO_Init(); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA0 ...

  7. 三、CSS样式——表格

    1.CSS表格 CSS表格属性可以帮助我们极大的改善表格的外观 2.表格边框 3.折叠边框 4.表格宽高 5.表格文本对齐 6.表格内边距  7.表格颜色 <!--index.html--> ...

  8. java锁

    ---恢复内容开始--- synchronized 互斥锁 synchronized(this) 当前类的所有synchronized(this) 都被锁了,还有synchronized static ...

  9. php中一个"异类"语法: $a && $b = $c; 【转载】

    $a = 1;$b = 2;$c = 3;$a && $b = $c;echo "a:$a";echo "b:$b";echo "c: ...

  10. js基本知识

    1.js中的数据类型: js中的数据类型有undefined,boolean,number,string,object等5种,前4种为原始类型,第5种为引用类型. 2.typeof 返回的是字符串,有 ...