Coding.net原码仓库地址:https://git.coding.net/laolaf/sw.git

目录

1 需求分析

2 功能设计

3 设计实现

4 算法详解

5 测试运行

6 满意代码

1 需求分析

用户分析:本软件的用户是小学生,因此,要对数据和算式进行限定。
限定条件总结如下:

1 数据是不超过1000的正整数;

2 运算符在3到5个之间;

3 运算过程中不能产生负数或分数(基本功能中)。

本软件具有以下功能:

1 接受参数n后可自动生成n道至少包含2种运算符的练习题,且不出现非整数或负数。

2 生成练习题后,学号与生成的n道练习题及其对应的正确答案输出到文件“result.txt”中。

3 在拓展类进行复杂真分数运算。

2 功能设计

基本功能:随机生成只有正整数的四则运算算式和答案。

扩展功能:a 支持有括号的运算式,包括出题与求解正确答案。算式中存在的括号必须大于2个,且不得超过运算符的个数。

b   扩展程序功能支持真分数的出题与运算,例如:1/6 + 1/8 + 2/3= 23/24。实现本功能时,支持运算时分数的自动化简。

模块设计:

1 Cal方法:用于转化字符串并计算得到的算式的值,支持括号运算。

2 Create方法:用于生成符合要求的算式的字符串形式。

3 Add方法:支持真分数运算的模块 。

4 main方法:输出

3 设计实现

本软件的类:Main。主要用到了2个方法。可完成以下功能:

  1. 基本四则运算:功能由Cal和Create完成,由Create产生合法的(运算中不出现负数和分数)的算式,再利用Cal计算。
  2. 加括号的四则运算:没做。

方法:

1 Cal(String str):实现计算一个多运算符的算式。参数str即是要进行运算的字符串。在算法详解中会提到。

2 CreateQuestion(int p):实现创造一个合法的算式。参数p是运算符号的个数。

它的主体:

  1. public static String CreateQuestion(int p) {// 产生1个包含p个运算符的四则运算的方法
  2. String re = "";//result
  3.  
  4. char oper[]={'+','-','*','÷'};//operator
  5. int Num[]=new int[30];//存储算式中的运算数
  6. char Op[]=new char[30];//xxxxxx 运算符
  7.  
  8. for(int he=p;he>0;he--){
  9. Op[he]=oper[(int) (Math.random()*4)];
  10. }
  11.  
  12. for(int he=p+1;he>0;he--){
  13. Num[he]=(int) (Math.random()*100);
  14. }
  15.  
  16. //谢绝野蛮连成连÷
  17. for(int e=p;e>0;e--){
  18. if(Op[e]=='*'||Op[e]=='÷')
  19. while(Op[e]!='*'&&Op[e]!='÷')
  20. Op[1+e]=oper[(int) (Math.random()*4)];
  21. }
  22.  
  23. //合法性问题:1 负数 2 分数.
  24. //先对乘除处理,处理之后,归纳为简单加减运算'
  25.  
  26. /* 解决分数问题 */
  27. for(int e=p;e>0;e--){
  28. if(Op[e]=='÷') Num[e-1]*=Num[e+1];
  29.  
  30. }
  31.  
  32. /*控制fu数问题,先计算已经产生的字符串,控制减数永远比被减数小,同时注意减数不能小于o*/
  33. for(int e=0;e<p;e++){
  34. if(Op[e] == '-')
  35. {
  36. String Caled= "" + Num[0];
  37. for(int c=0; c<p; c++)
  38. Caled= Caled + Op[c] + Op[c+1];
  39. int existed = Cal(Caled);
  40. Num[e+1] = existed-(int) (Math.random()*existed);
  41. };
  42.  
  43. }
  44.  
  45. re=re+Num[0];
  46. for(int pp=0;pp<p;pp++)
  47. re=re+Op[pp]+Num[pp+1];
  48. return re;//返回一个合法的算式
  49.  
  50. }

4 算法详解

用到的主要算法是逆波兰表达式和调度场算法---用来计算字符串状态下算式的值。

参考了链接:https://liam0205.me/2016/12/14/Shunting-Yard-Algorithm/]

这里讲得很清楚了:

简单地说,就是先将要输入的表达式存入list中,然后,将表达式变为逆波兰表达式压入栈内,通过正则判断字符串是否为数字,是,输出到集合里,不是,则进行优先级的判断,括号的级别最高,其次是乘除,然后是加减。

部分代码:

  1. List<String> list = (List<String>) new ArrayList<>();
  2. Collections.addAll(list, expression);
  3.  
  4. Stack<String> stack = new Stack<>();
  5.  
  6. List<String> RPNList = new ArrayList<>();
  7.  
  8. String numRegex = "^-?[0-9]+$";
  9.  
  10. for(String s : list) {
  11. if(s.matches(numRegex)) {
  12.  
  13. RPNList.add(s);
  14. }else if("*".equals(s) || "/".equals(s) || "+".equals(s) || "-".equals(s)) {
  15.  
  16. if(stack.isEmpty()) {
  17. stack.push(s);
  18. }else{
  19. int currLevel = getLevel(s);
  20. String topStr = stack.peek();
  21. int topLevel = getLevel(topStr);
  22. if (currLevel <= topLevel) {
  23. // 栈顶元素依次出栈并输出
  24. while(!stack.isEmpty()) {
  25. // 遇到左括号退出
  26. String peek = stack.peek();
  27. if("(".equals(peek)) {
  28. break;
  29. }
  30. RPNList.add(stack.pop());
  31. }
  32. }
  33. stack.push(s);
  34. }
  35. }else if("(".equals(s)) {
  36. stack.push(s);
  37. }else if(")".equals(s)) {
  38. // 栈顶元素依次出栈并输出
  39. int length = stack.size();
  40. for(int i = 0; i < length; i++) {
  41. String pop = stack.pop();
  42. // 遇到左括号退出 并丢弃“”"("
  43. if("(".equals(pop)) {
  44. break;
  45. }
  46. RPNList.add(pop);
  47. }
  48. }
  49. }
  50. // 如果栈中还有元素 弹出
  51. if(!stack.isEmpty()) {
  52. // 栈顶元素依次出栈并输出
  53. int length = stack.size();
  54. for(int i = 0; i < length; i++) {
  55. RPNList.add(stack.pop());
  56. }
  57. }

5 测试运行

6 满意的代码:

在对算式的合法性进行控制时,对除法的控制:

  1. //谢绝野蛮连成连÷
  2. for(int e=0;e<p;e++){
  3. if(Op[e]=='*'||Op[e]=='÷')
  4. Op[1+e]=oper[(int) (Math.random()*2)];
  5. if(Op[e]!='*'&&Op[e]!='÷')
  6. Op[1+e]=oper[(int) (Math.random()*4)];
  7. }
  8. //sffg
  9. //合法性问题:1 负数 2 分数.
  10. //先对乘除处理,处理之后,归纳为简单加减运算'
  11. /* 解决分数问题 */
  12. for(int e=0;e<p;e++){
  13. if(Op[e]=='÷')
  14. Num[e]=Num[e+1]*(int)(Math.random()*20);
  15.  
  16. if(Op[e]=='-')
  17. {
  18. Num[e+1]=(int)(Math.random()*Num[e]/8);
  19. // Num[e+2]=(int)(Math.random()*Num[e+1]);
  20. Num[e+2]=(int)(Math.random()*4)+1;
  21.  
  22. }
  23. }

首先避免了连÷(以及连*---这是防止数据过大),可以减少判断。然后,对整个算式进行搜索,发现符号为÷的,将除号前的被除数字乘上除数,这样永远不会出现未除尽的情况。

7 总结:完成这次作业最大的障碍就是语言问题,对于java过于陌生了些。另外,我觉得这次的作业还是可以体现模块化原则的,虽然我把所有的方法都写道一个类里面去了,但是功能是由各个组件独立完成的。

8 psp

PSP2.1

任务内容

计划共完成需要的时间(h)

实际完成需要的时间(h)

Planning

计划

0.5

0.5

·        Estimate

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

0.5

0.5

Development

开发

40

58.5

·        Analysis

·         需求分析 (包括学习新技术)

10.5

30

·        Design Spec

·         生成设计文档

0.5

0.5

·        Design Review

·         设计复审 (和同事审核设计文档)

0

0

·        Coding Standard

·         代码规范 (为目前的开发制定合适的规范)

0.5

1

·        Design

·         具体设计

1

1.5

·        Coding

·         具体编码

18

21

·        Code Review

·         代码复审

1

2

·        Test

·         测试(自我测试,修改代码,提交修改)

1

1

Reporting

报告

3

2

·         Test Report

·         测试报告

0.5

0.5

·         Size Measurement

·         计算工作量

0

0

·         Postmortem & Process Improvement Plan

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

0.5

0.5

     
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       
       

2016011998+sw的更多相关文章

  1. The Nine Indispensable Rules for HW/SW Debugging 软硬件调试之9条军规

    I read this book in the weekend, and decided to put the book on my nightstand. It's a short and funn ...

  2. 微软职位内部推荐-Sr. SW Engineer for Azure Networking

    微软近期Open的职位: Senior SW Engineer The world is moving to cloud computing. Microsoft is betting Windows ...

  3. 重新定位svn地址的方法(windows和linux),svn switch(sw)的帮助信息

    今天公司的路由器出现问题,服务器的IP地址也跟着变了,但是原来的svn已经设置好了,现在需要更换地址 查询原地址的方法: root@jack-desktop:codes# svn info 路径: . ...

  4. CopyU!SW新版发布!

    CopyU!SW新版发布,版本号为:2.1.412.213 主要更新内容如下: 此版本(2.1.412.213)主要作了如下更新:        1.修复了CopyU!SW版本中的运行模式规则的设定错 ...

  5. MDK5使用Jlink下载显示 no cortex m sw divice 解决办法

    问题: (1)下面界面中找不到设备 (2)下载程序的时候提示" no cortex m sw divice " 然后是"target dll has been cance ...

  6. 调研pwa和sw

    概述 处于好奇,最近我调研了一下pwa和service worker,有些新的,记录下来,供以后开发时参考,相信对其他人也有用.pwa主要是通过service worker实现的,它主要包括桌面图标, ...

  7. yum解决 "Couldn't resolve host 'apt.sw.be'" 错误

    1.yum无法安装工具    failure: repodata/repomd.xml from dag: [Errno 256] No more mirrors to try.http://apt. ...

  8. tunnel sw

    tunnel sw openssh vpn httprltunnel BarbaTunnel ngrok Chisel https://github.com/jpillora/chisel/blob/ ...

  9. [na]二层sw数据交换

    1,同vlan下,两台pc配置了GW,arp请求过程. Pc1 ping pc0的时候,触发pc1的arp请求,发给GW后,GW继续发给pc0(同一个vlan),pc0收到后给pc1回复.Pc1发出i ...

随机推荐

  1. Bugku Writeup —文件上传2(湖湘杯)

    我们先来看下题目,题目说明是文件上传 我们可以尝试通过构造payload来进行测试 php://filter/read=convert.base64-encode/resource=flag 获取到f ...

  2. angularjs animation

    http://augus.github.io/ngAnimate/ http://www.nganimate.org/angularjs/ng-repeat/move http://codepen.i ...

  3. 2017-2018-2 《网络对抗技术》20155322 Exp6 信息搜集与漏洞扫描

    [-= 博客目录 =-] 1-实践目标 1.1-实践介绍 1.2-实践内容 1.3-实践要求 2-实践过程 2.1-Google hacking & ZoomEye 2.2-DNS.IP信息收 ...

  4. WPF不同线程之间的控件的访问

    原文:WPF不同线程之间的控件的访问 WPF不同线程之间的控件是不同访问的,为了能够访问其他线程之间的控件,需要用Dispatcher.Invoke执行一个新的活动即可. 例如: public voi ...

  5. 如何搭建openvpn

    一.什么是openvpn Openvpn是一款基于openssl的开源vpn软件,它可以很好的运行在linux及windows各发行版本中,它的核心技术是虚拟网卡,其实它更像是一个底层的网卡驱动软件, ...

  6. Redis 为什么使用单进程单线程方式也这么快

    Redis 采用的是基于内存的采用的是单进程单线程模型的 KV 数据库,由 C 语言编写.官方提供的数据是可以达到100000+的 qps.这个数据不比采用单进程多线程的同样基于内存的 KV 数据库 ...

  7. java多线程系列(一)---多线程技能

    java多线程技能 前言:本系列将从零开始讲解java多线程相关的技术,内容参考于<java多线程核心技术>与<java并发编程实战>等相关资料,希望站在巨人的肩膀上,再通过我 ...

  8. (转)js数组与字符串的相互转换方法

    一.数组转字符串 需要将数组元素用某个字符连接成字符串,示例代码如下: var a, b; a = new Array(0,1,2,3,4); b = a.join("-"); 二 ...

  9. CSS过渡动画之transition

    O(∩_∩)O~ 这两天在看看CSS的相关内容,关于transition动画感觉很有意思,分享一下. CSS负责给html加效果,自然少不了各种动画,今天介绍一下transition. 概述 看一段比 ...

  10. 做一个树莓派Raspberry Pi拍立得

    用树莓派Raspberry Pi打造一台拍立得,作法如下: 材料:树莓派+数字相机模块+热敏打印机 因为打印机所需电流较高,所以电源供应器的规格需要5V 3A以上. 再找一个稳定的电源以及够大的外壳装 ...