码迷,mamicode.com
首页 > 其他好文 > 详细

个人实践项目——四则运算

时间:2018-03-21 11:39:57      阅读:183      评论:0      收藏:0      [点我收藏+]

标签:pos   入参   spec   独立   java语言   analysis   循环   odi   判断   

个人实践——四则运算

一、需求分析:

(一)功能需求

1、基本功能:

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

2、扩展功能

支持有括号的运算式,包括出题与求解正确答案。

支持真分数的出题与运算。

(二)非功能需求

1、每个数字在 0 和 100 之间,运算符在3个到5个之间。

2、所出的练习题在运算过程中不得出现负数与非整数,比如3÷5+2=2.6,2-5+10=7等是不合法的。

3、算式中存在的括号必须大于2个,且不得超过运算符的个数。

4、真分数只需要涵盖加减法

5、支持运算时分数的自动化简,且计算过程中与结果都须为真分数。

6、格式要求如下:

当程序接收的参数为4时,以下为一个输出文件示例。

2018010203

13+17-1=29

11*15-5=160

3+10+4-16=1

15÷5+3-2=4

(三)设计需求

1、只能使用Java语言。

2、生成文件时请使用相对路径,生成的txt 文件需在项目的根目录下,可直接查看演示示例。

3、使用的JDK版本为 jdk8u161。

4、使用的JRE版本为jre8u161。

5、不得使用除限定版本jdk与jre外的额外依赖包。

二、功能设计:

(一)基本功能

1、能生成文件,假如文件生成有误,会报错,会有提示。

2、输入的保证是数字,如果不是数字,会有提示,并且可以重新输入。

3、输入一个参数n,然后随机产生n道加减乘除算术题。保证加减乘除四个运算符的相对平衡,出现的次数相对均等。尽量能出现连除,连减的算术题。且保证在算数过程中,不出现负数,和小数。

4、在没仔细看要求之前,我打算生成一个窗口,同学可以输入答案,并且可以进行判断正误,然后给出结果。

(二)扩展功能

1、在生成括号的过程中,打算随机生成括号,并且保证括号的合法性。比如(3*8)+5=29;  6+(7)*8=62;  (2*3+4)=10; 等式子是不合法的。

2、在生成分数的过程中,保证生成真分数,并且化成最简的。

3、在计算真分数的过程中,保证过程中不会出现假分数和负数。因为没有乘除运算,所以不用考虑优先级,可以边生成边运算。且保证结果是最简真分数。

三、设计实现

(一)优先级类

功能:此类是一个带参的有返回值的类,返回的是一个整数(int)。

目的:通过返回来的int的大小,从而来判断符号的优先级。

关系:此类是一个内部类,可以直接调用使用。

此类较简单,未画流程图。

(二)gcd 类

功能:此类是一个带参的有返回值的类,返回的是一个整数,此整数是两个数的最大公因数。

目的:此类通过辗转相除法计算两个数的最大公因数,为了生成最简真分数和化简最终结果。

关系:此类还是一个内部类,可以直接调用。

流程图

技术分享图片

(三)两个函数相互独立。

四、算法详解

(一)文件生成

要求:能生成文件,假如文件生成有误,会报错,会有提示。

要完成这个功能,需要使用PrintStream类,为了生成的txt 文件需在项目的根目录下,则需要直接使用"result.txt",不加任何路径。

1 try {
2     PrintStream ps = new PrintStream("result.txt");
3     System.setOut(ps);
4 }catch(Exception e) {
5     System.out.println("文件生成错误");
6 }

 

(二)输入整数

要求:输入的保证是数字,如果不是数字,会有提示,并且可以重新输入。

要实现这个功能,需要使用字符转化来判断是否是数字字符串,从而转化成数字。需要使用Integer.valueOf(String);语句。为了能重新输入需要使用while(true)加break;

 1 while(true)
 2 {
 3     n=input.nextLine();
 4     flag=1;
 5     try 
 6     {
 7         int num=Integer.valueOf(n);//把字符串强制转换为数字
 8     }
 9     catch (Exception e) 
10     {
11         System.out.println("输入的不是数字,请重新输入:");
12         flag=0;
13     }
14     if(flag==1)break;//退出循环
15 }

 

(三)随机数的使用

要求:保证加减乘除四个运算符的相对平衡,出现的次数相对均等,不出现负数,和小数。需要使用“数组+随机数”。

 1 char[] arr= {‘+‘,‘-‘,‘*‘,‘÷‘};
 2 int temp=rand.nextInt(4);
 3 charArr=arr[temp];
 4 
 5 while(a0%a1!=0)
 6 {
 7     a0=rand.nextInt(100);
 8     a1=rand.nextInt(99)+1;
 9 }
10 while(a0<a1)
11 {
12     a0=rand.nextInt(100);
13     a1=rand.nextInt(100);
14 }

如果不能乘除或者a0-a1<0,则会重新生成随机数。

(四)保证括号的合法性

为了不生成(3*8)+5=29;  6+(7)*8=62;  (2*3+4)=10;此类括号。我们需要对优先级进行判断,如果前者优先级低于后者,则会生成括号。

 1 if(panduan(charArr)<panduan(charArr2))//优先级判断
 2 {
 3     if(charArr2==‘÷‘)
 4     {
 5         if(b0==0)b0++;
 6         while(sum%b0!=0)//如果不能整除 重新生成随机数
 7         {
 8             b0=rand.nextInt(99)+1;
 9         }
10             sum=sum/b0;
11     }
12     if(charArr2==‘*‘)sum=sum*b0;
13     brr="("+brr+")"+""+charArr2+""+b0;//满足条件 生成括号
14 }

 注释:panduan()是一个内部类,用来判断符号优先级。

(五)panduan——优先级类的实现

1 public static int panduan(char c)//判断优先级
2 {
3     if(c==‘(‘)return 0;
4     if(c==‘+‘||c==‘-‘)return 1;
5     if(c==‘*‘||c==‘÷‘)return 2;
6     return -1;
7 }

(六)最大公因数——gcd类

要求:在生成分数的过程中,保证生成真分数,并且化成最简的。需要使用辗转相除法求最大公因数,然后分子分母同除以最大公因数化简。保证是真分数的代码和保证非负数的代码类似,就不写出来了。

 1 public static int gcd(int x,int y)
 2 {
 3     while(true)
 4     {
 5         if(x%y==0)return y;
 6         int temp=y;
 7         y=x%y;
 8         x=temp;
 9     }
10 }

 五、测试运行

技术分享图片 

六、代码

在计算值得过程中,用到了栈的思想。但是我的思路主要还是,边生成边运算。即生成完毕后,结果就直接出来了。

 1 for(int i=1;i<charCoun;i++)
 2 {
 3     int temp1=rand.nextInt(4);
 4     char charArr2=arr[temp1];
 5     int b0=rand.nextInt(100);
 6     if(panduan(charArr)<panduan(charArr2))//优先级判断
 7     {
 8         if(charArr2==‘÷‘)
 9         {
10             if(b0==0)b0++;
11             while(sum%b0!=0)//如果不能整除 重新生成随机数
12             {
13                 b0=rand.nextInt(99)+1;
14             }
15             sum=sum/b0;//计算
16         }
17         if(charArr2==‘*‘)sum=sum*b0;
18         brr="("+brr+")"+""+charArr2+""+b0;//满足条件 生成括号
19     }
20     else
21     {
22         if(charArr2==‘÷‘)
23         {
24             if(b0==0)b0++;
25             while(sum%b0!=0)
26             {
27                 b0=rand.nextInt(99)+1;
28             }
29             sum=sum/b0;//计算
30         }
31         if(charArr2==‘-‘)
32         {
33             while(sum<b0)
34                     {
35                 b0=rand.nextInt(100);
36             }
37             sum=sum-b0;
38         }
39         if(charArr2==‘+‘)sum=sum+b0;//计算
40         if(charArr2==‘*‘)sum=sum*b0;//计算
41         brr=brr+""+charArr2+""+b0;
42     }
43     charArr=charArr2;
44 }
45         

 

此代码根据优先级,生成括号。

 1 if(panduan(charArr)<panduan(charArr2))//优先级判断
 2 {
 3     if(charArr2==‘÷‘)
 4     {
 5         if(b0==0)b0++;
 6         while(sum%b0!=0)//如果不能整除 重新生成随机数
 7         {
 8             b0=rand.nextInt(99)+1;
 9         }
10         sum=sum/b0;
11     }
12     if(charArr2==‘*‘)sum=sum*b0;
13     brr="("+brr+")"+""+charArr2+""+b0;//满足条件 生成括号
14 }

七、总结

1、对任务进行逐步分解和细化,分成若干个子任务,每个子任务只完成部分完整功能,并且可以通过函数来实现;比如此四则运算中的panduan类和gcd类。通过生成两个内部类,使程序模块化,来简化代码。最后在主函数中进行调用实现。

2、降低耦合,控制了程序设计的复杂性,提高了代码的重用性。但是由于个人编程习惯问题,仍有一些功能没有进行模块化。之后我会对博客和代码进行更新。

八、PSP

PSP

任务内容

计划时间(min)

完成时间(min)

Planning

计划

3

3

     Estimate

    估计这个任务需要多少时间,并规划大致工作步骤

3

3

Development

开发

145

305

    Analysis

    需求分析

10

15

    Design Spec

    生成文档

0

0

    Design Review

    设计复审

0

0

    Coding Standard

    代码规范

0

0

    Design

    具体设计

30

50

    Coding

    具体编码

90

60

    Code Review

    代码复审

0

0

    Test

    测试

15

180

Reporting

报告

120

210

    Test Report

    测试报告

0

0

    Size Measurement

    计算工作量

0

0

   Postmortem& ProcessImprovement Plan

    事后总结, 并提出过程改进计划

120

210

1、因为没有生成文件等一系列过程,导致在具体设计和代码编写的时候花了大量时间。尤其是测试,一直出现bug,调bug花了我大量时间。

2、因为是个人项目,所以感觉自己能看懂就行,不用管其他人,所以一些过程就直接略过了。在以后团队工作中,我会认真完成各项工作,方便未来的修改。

九、完整代码

  1 import java.util.Random;
  2 import java.util.Scanner;
  3 import java.io.PrintStream;
  4 public class Main {
  5 
  6     public static int panduan(char c)//判断优先级
  7     {
  8         if(c==‘(‘)return 0;
  9         if(c==‘+‘||c==‘-‘)return 1;
 10         if(c==‘*‘||c==‘÷‘)return 2;
 11         return -1;
 12     }
 13     
 14     public static int gcd(int x,int y)
 15     {
 16         while(true)
 17         {
 18             if(x%y==0)return y;
 19             int temp=y;
 20             y=x%y;
 21             x=temp;
 22         }
 23     }
 24     
 25     public static void main(String[] args) {
 26         // TODO Auto-generated method stub
 27         Scanner input = new Scanner(System.in);
 28         String n;
 29         int flag=1;
 30         try {
 31             PrintStream ps = new PrintStream("result.txt");
 32             System.setOut(ps);
 33         }catch(Exception e) {
 34             System.out.println("文件生成错误");
 35         }
 36         while(true)
 37         {
 38             n=input.nextLine();
 39             flag=1;
 40             try 
 41             {
 42                 int num=Integer.valueOf(n);//把字符串强制转换为数字
 43             }
 44             catch (Exception e) 
 45             {
 46                 System.out.println("输入的不是数字,请重新输入:");
 47                 flag=0;
 48             }
 49             if(flag==1)break;//退出循环
 50         }
 51         int n1=Integer.valueOf(n);
 52         System.out.println("2016012090");
 53         Random rand = new Random();
 54         char charArr;
 55         int coun=0;
 56         while(true)
 57         {
 58             if(coun==n1)break;
 59             int temp2=rand.nextInt(4);
 60             if(temp2!=0)
 61             {
 62                 char[] arr= {‘+‘,‘-‘,‘*‘,‘÷‘};
 63                 String brr="";
 64                 int sum=0;
 65                 int charCoun=rand.nextInt(3)+3;
 66                 int temp=rand.nextInt(4);
 67                 charArr=arr[temp];
 68                 int a0=rand.nextInt(100);
 69                 int a1=rand.nextInt(100);
 70                 if(charArr==‘÷‘)
 71                 {
 72                     if(a1==0)a1++;
 73                     while(a0%a1!=0)
 74                     {
 75                         a0=rand.nextInt(100);
 76                         a1=rand.nextInt(99)+1;
 77                     }
 78                     sum=a0/a1;
 79                 }
 80                 if(charArr==‘-‘)
 81                 {
 82                     while(a0<a1)
 83                     {
 84                         a0=rand.nextInt(100);
 85                         a1=rand.nextInt(100);
 86                     }
 87                     sum=a0-a1;
 88                 }
 89                 if(charArr==‘+‘)sum=a0+a1;
 90                 if(charArr==‘*‘)sum=a0*a1;
 91                 brr=a0+""+charArr+""+a1;
 92                 for(int i=1;i<charCoun;i++)
 93                 {
 94                     int temp1=rand.nextInt(4);
 95                     char charArr2=arr[temp1];
 96                     int b0=rand.nextInt(100);
 97                     if(panduan(charArr)<panduan(charArr2))//优先级判断
 98                     {
 99                         if(charArr2==‘÷‘)
100                         {
101                             if(b0==0)b0++;
102                             while(sum%b0!=0)//如果不能整除 重新生成随机数
103                             {
104                                 b0=rand.nextInt(99)+1;
105                             }
106                             sum=sum/b0;
107                         }
108                         if(charArr2==‘*‘)sum=sum*b0;
109                         brr="("+brr+")"+""+charArr2+""+b0;//满足条件 生成括号
110                     }
111                     else
112                     {
113                         if(charArr2==‘÷‘)
114                         {
115                             if(b0==0)b0++;
116                             while(sum%b0!=0)
117                             {
118                                 b0=rand.nextInt(99)+1;
119                             }
120                             sum=sum/b0;
121                         }
122                         if(charArr2==‘-‘)
123                         {
124                             while(sum<b0)
125                             {
126                                 b0=rand.nextInt(100);
127                             }
128                             sum=sum-b0;
129                         }
130                         if(charArr2==‘+‘)sum=sum+b0;
131                         if(charArr2==‘*‘)sum=sum*b0;
132                         brr=brr+""+charArr2+""+b0;
133                     }
134                     charArr=charArr2;
135                 }
136                 System.out.println(brr+"="+sum);
137             }
138             else
139             {
140                 String brr2="";
141                 char[] arr1= {‘+‘,‘-‘};
142                 int sumx=0;
143                 int sumy=0;
144                 int charCoun1=rand.nextInt(3)+3;
145                 int temp1=rand.nextInt(2);
146                 charArr=arr1[temp1];
147                 int num0x=rand.nextInt(20);
148                 int num0y=rand.nextInt(19)+1;
149                 int num1x=rand.nextInt(20);
150                 int num1y=rand.nextInt(19)+1;
151                 int g;
152                 g=gcd(num0x,num0y);
153                 num0x/=g;
154                 num0y/=g;
155                 g=gcd(num1x,num1y);
156                 num1x/=g;
157                 num1y/=g;
158                 while(num0x>=num0y||num1x>=num1y)
159                 {
160                     num0x=rand.nextInt(20);
161                     num0y=rand.nextInt(19)+1;
162                     num1x=rand.nextInt(20);
163                     num1y=rand.nextInt(19)+1;
164                     g=gcd(num0x,num0y);
165                     num0x/=g;
166                     num0y/=g;
167                     g=gcd(num1x,num1y);
168                     num1x/=g;
169                     num1y/=g;
170                 }
171                 if(charArr==‘-‘)
172                 {
173                     while(num0x*num1y-num0y*num1x<0)
174                     {
175                         num1x=rand.nextInt(20);
176                         num1y=rand.nextInt(19)+1;
177                         g=gcd(num1x,num1y);
178                         num1x/=g;
179                         num1y/=g;
180                     }
181                     sumx=num0x*num1y-num0y*num1x;
182                     sumy=num0y*num1y;
183                 }
184                 if(charArr==‘+‘)
185                 {
186                     while(num0x*num1y+num0y*num1x>=num0y*num1y)
187                     {
188                         num1x=rand.nextInt(20);
189                         num1y=rand.nextInt(19)+1;
190                         g=gcd(num1x,num1y);
191                         num1x/=g;
192                         num1y/=g;
193                     }
194                     sumx=num0x*num1y+num0y*num1x;
195                     sumy=num0y*num1y;
196                 }
197                 brr2=num0x+"/"+num0y+""+charArr+""+num1x+"/"+num1y;
198                 for(int i=1;i<charCoun1;i++)
199                 {
200                     temp1=rand.nextInt(2);
201                     charArr=arr1[temp1];
202                     int num2x=rand.nextInt(20);
203                     int num2y=rand.nextInt(19)+1;
204                     while(num2x>=num2y)
205                     {
206                         num2x=rand.nextInt(20);
207                         num2y=rand.nextInt(19)+1;
208                         g=gcd(num2x,num2y);
209                         num2x/=g;
210                         num2y/=g;
211                     }
212                     if(charArr==‘-‘)
213                     {
214                         while(sumx*num2y-sumy*num2x<0)
215                         {
216                             num2x=rand.nextInt(20);
217                             num2y=rand.nextInt(19)+1;
218                             g=gcd(num2x,num2y);
219                             num2x/=g;
220                             num2y/=g;
221                         }
222                         sumx=sumx*num2y-sumy*num2x;
223                         sumy=sumy*num2y;
224                     }
225                     if(charArr==‘+‘)
226                     {
227                         while(sumx*num2y+sumy*num2x>sumy*num2y)
228                         {
229                             num2x=rand.nextInt(20);
230                             num2y=rand.nextInt(19)+1;
231                             g=gcd(num2x,num2y);
232                             num2x/=g;
233                             num2y/=g;
234                         }
235                         sumx=sumx*num2y+sumy*num2x;
236                         sumy=sumy*num2y;
237                     }
238                     brr2=brr2+""+charArr+""+num2x+"/"+num2y;
239                 }
240                 g=gcd(sumx,sumy);
241                 if(sumx==0)System.out.println(brr2+"="+sumx);
242                 else System.out.println(brr2+"="+sumx/g+"/"+sumy/g);
243             }
244             coun++;
245         }
246     }
247 
248 }

 

 

个人实践项目——四则运算

标签:pos   入参   spec   独立   java语言   analysis   循环   odi   判断   

原文地址:https://www.cnblogs.com/xia520/p/8615109.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!