20162317-20162315结对编程(四则运算)第一周阶段总结
-
四则运算
需求分析
- 实现任意个数运算数的四则运算。我们已经写过一个后缀表达式,所以我们需要将中缀表达式转化为后缀表表达式。
- 使用写过的后缀表达式计算器程序进行四则运算
- 设置一个类能输入一道小学生计算题,用户能输入答案并且系统给出评判。
- 先设计一个类,之中包含生成随机数,进行计算,在测试驱动类中类中给出用户选择题目个数的选项,然后对每一道题目进行比较,输出对错。
设计思路
在前几周的java学习中,我们曾经尝试用栈来进行若干个数的后缀表达式的运算,因此该次的四则运算也是可以用到上次方法:
- 后缀表达式可以避免系统识别括号的问题,所以这次我们的编程继续使用后缀表达式。所以程序的第一步我们需要将用户的中缀表达式转换为后缀表达式。然后根据上一次的例子仿写一个计算后缀表达式的一个计算类
- 简单的Setquesion类里,我们实现了两个50内的随机数数的四则运算。
import java.util.Random;
import java.util.Scanner;
/**
* Created by Funny_One on 2017/5/9.
*/
public class SetQuestion {
private int j = 0, s = 1;
Random r = new Random();
Scanner sca = new Scanner(System.in);
public SetQuestion(int g) {
if (g == j) {
int sym = 0;
junior jr = new junior();
System.out.println("How many questions do you want to try ?");
int choice = sca.nextInt();
for (int i = 1; i <= choice; i++) {
sym = r.nextInt(2);
if (sym == 0) {
jr.add();
jr.judge();
}
if (sym == 1) {
jr.minus();
jr.judge();
}
}
System.out.println("You have solved "+choice+" questions.");
System.out.println(jr.R+" questions are RIGHT");
System.out.println(jr.W+" questions are WRONG");
} else if (g == s) {
int sym = 0;
senior sr = new senior();
System.out.println("How many questions do you want to try ?");
int choice = sca.nextInt();
for (int i = 1; i <= choice; i++) {
sym = r.nextInt(3);
if (sym == 0) {
sr.add();
sr.judge();
}
if (sym == 1) {
sr.minus();
sr.judge();
}
if (sym == 2) {
sr.multiply();
sr.judge();
}
if (sym == 3) {
sr.div();
sr.judge();
}
}
System.out.println("You have solved "+choice+" questions.");
System.out.println(sr.R+" questions are RIGHT");
System.out.println(sr.W+" questions are WRONG");
}
}
}
setQuestion中它分别新建了junior以及senior的对象,而junior是代表低级运算的类只涉及加减方法,senior是代表高级运算的类,涉及的是加减乘除。
junior:
import java.util.Random;
import java.util.Scanner;
/**
* Created by Funny_One on 2017/5/9.
*/
public class junior {
private int j1, j2 , result = 0;
Random r = new Random();
public int R=0,W=0;
Scanner sca = new Scanner(System.in);
Scanner sa = new Scanner(System.in);
private void setJ1() {
j1 = r.nextInt(51);
}
private void setJ2() {
j2 = r.nextInt(51);
}
private double getJ1() {
return j1;
}
private double getJ2() {
return j2;
}
private void Sng(){
setJ1();
setJ2();
getJ1();
getJ2();
}
public double add() {
Sng();
result = j1 + j2;
System.out.println(j1+"+"+j2+"=");
return result;
}
public double minus() {
Sng();
if (j1 >= j2) {
result = j1 - j2;
System.out.println(j1 + "-" + j2 + "=");
}
else {
result = j2 - j1;
System.out.println(j2 + "-" + j1 + "=");
}
return result;
}
public void judge(){
String choose ="y";
while (choose.equalsIgnoreCase("y")){
System.out.println("Your answer is : ");
int answer = sca.nextInt();
if(answer == result){
R++;
System.out.println("Congratulations, you are right.");
break;
}else{
W++;
System.out.println("You are WRONG, try again?(y/n)");
choose = sa.nextLine();
if(choose.equalsIgnoreCase("n")){
System.out.println("The result is: "+result);
}
}
}
}
}
senior:
import java.util.Random;
import java.util.Scanner;
/**
* Created by Funny_One on 2017/5/9.
*/
public class senior {
private int s1 = 0, s2 = 0, result = 0;
public int R =0,W=0;
private int s3=0,s4=0;
Random r = new Random();
private int IN =1,FS=0,J=r.nextInt(2);
Scanner sca = new Scanner(System.in);
Scanner sa = new Scanner(System.in);
private void setS1() {
s1 = r.nextInt(51);
this.s1 = s1;
}
private void setS2() {
s2 = r.nextInt(51);
}
private void setS3(){
s3 =r.nextInt(10)+1;
}
private void setS4(){
s4 = r.nextInt(10)+1;
}
private int getS1() {
return s1;
}
private int getS2() {
return s2;
}
private int getS3(){
return s3;
}
private int getS4(){
return s4;
}
private void SnG(){
setS1();
setS2();
setS3();
setS4();
getS1();
getS2();
getS3();
getS4();
}
public double add() {
SnG();
if (J == IN) {
result = s1 + s2;
System.out.println(s1 + "+" + s2 + "=");
}
return result;
}
public double minus() {
SnG();
if (J == IN) {
if (s1 >= s2) {
result = s1 - s2;
System.out.println(s1 + "-" + s2 + "=");
} else {
result = s2 - s1;
System.out.println(s2 + "-" + s1 + "=");
}
}
return result;
}
public double multiply() {
SnG();
if (J == IN) {
result = s1 * s2;
System.out.println(s1 + "x" + s2 + "=");
}
return result;
}
public double div() {
SnG();
if (J == IN) {
result = s1 / s2;
System.out.println(s1 + "/" + s2 + "=");
}
return result;
}
public void judge() {
String choose = "y";
if (J == IN) {
while (choose.equalsIgnoreCase("y")) {
System.out.println("Your answer is : ");
int answer = sca.nextInt();
if (answer == result) {
R++;
System.out.println("Congratulations, you are right.");
break;
} else {
W++;
System.out.println("You are WRONG, try again?(y/n)");
choose = sa.nextLine();
if (choose.equalsIgnoreCase("n")) {
System.out.println("The result is: " + result);
}
}
}
}
}
}
- 高级一点的SetquesitonV2里,可以实现多个运算数计算(我们限制在了6个数以内)。我们植入了编写过的中缀表达式转后缀表达式的方法。再进行后缀表达式计算。
- 程序的关键:中缀表达式转为后缀表达式,我们将这个代码放在Setquesiton里面,暂时不考虑括号:例如3+3,符号进栈,再压入两个数字,这样将他们从栈中取出的时候就是3 3 +,而多运算数中缀表达式满足符号在数字之后的形式,因此形成以下代码。
SetquestionV2:
import java.io.FileWriter;
import java.util.List;
import java.util.Scanner;
import java.util.Random;
import java.util.Stack;
/**
* Created by Funny_One on 2017/5/11.
*/
public class SetQuestionV2 {
private int chseNum = 0, chseDif = 0,answer=0;
private Scanner sca = new Scanner(System.in);
private Random r = new Random();
public String[] token = {"+", "-", "X", "/"};
public String[] middle;
private Stack<String>sta;
FileWriter fw;
cal c =new cal();
//Design the number of questions that the customers want to try.
public int setQuestionNum() {
System.out.println("How many questions do you want to try?");
chseNum = sca.nextInt();
return chseNum;
}
//Design the difficulty which the customer want to try, of the question
public int setDifficluty() {
System.out.println("What level do you want to challenge ?(from 1 to 5)");
chseDif = sca.nextInt();
return chseDif;
}
//Print the qustions
public void offerQuestion() throws Exception{
middle = new String[2 * (chseDif + 1)];
for (int t = 1; t <= chseNum; t++) {
fw = new FileWriter("Save");
for (int i = 0; i < middle.length; i += 2) {
int Num = r.nextInt(30)+1;
String strNum = String.valueOf(Num);
middle[i] = strNum;
}
for (int i = 1; i < middle.length; i += 2) {
middle[i] = token[r.nextInt(4)];
if (i == middle.length - 1) {
middle[i] = "=";
}
}
for (int q = 0; q < middle.length; q++) {
System.out.print(middle[q]+" ");
}
//后缀表达式的转换
sta =new Stack<String>();
//逐个审查判断
for(int i =0;i<middle.length-1;i++) {
//符号优先级高的
if (isOperatorFirst(middle[i])) {
sta.push(middle[i]);
}
//符号优先级较低的
else if (isOperatorLatter(middle[i])) {
//若栈空,则入栈。
if(sta.empty()){
sta.push(middle[i]);
}
//若栈不空,栈中符号全部弹出
else{
for(int k=0;k<(i-1)/2;k++){
fw.append(sta.pop()+" ");
}
sta.push(middle[i]);
}
}
//数字直接输出
else{
fw.append(middle[i]+" ");
}
}
while(!sta.empty()){
fw.append(sta.pop()+" ");
}
fw.append("
");
fw.flush();
answer = sca.nextInt();
c.Cal();
c.judge(answer);
}
}
//判断是否为符号,若是符号再判断是否优先级
private boolean isOperatorLatter(String token){
return (token.equals("+")||token.equals("-"));
}
private boolean isOperatorFirst(String token){
return (token.equals("X")||token.equals("/"));
}
}
Cal:
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.Stack;
import java.util.ArrayList;
/**
* Created by Funny_One on 2017/5/12.
*/
public class cal {
/** constant for addition symbol */
private final char ADD = '+';
/** constant for subtraction symbol */
private final char SUBTRACT = '-';
/** constant for multiplication symbol */
private final char MULTIPLY = 'X';
/** constant for division symbol */
private final char DIVIDE = '/';
//Read File Save.txt
private FileReader fr;
private BufferedReader br;
//存放读取结果
private String[] Save;
Stack<Integer> num = new Stack<Integer>();
private int result=0;
public int Cal()throws Exception{
int op1,op2;
fr = new FileReader("Save");
br = new BufferedReader(fr);
//改循环用于读取题目
Save = br.readLine().split(" ");
//该循环是用于逐个检测是否为符号,并进行进栈和出栈
for(int i=0;i<Save.length;i++){
if(isOperator(Save[i])){
op2 = (num.pop()).intValue();
op1 = (num.pop()).intValue();
result = evalSingleOp(Save[i].charAt(0),op1,op2);
num.push(result);
}else{
//System.out.println(Save[i]);
num.push(Integer.parseInt(Save[i]));
}
}
return result;
}
public void judge(int answer){
if(answer == result){
System.out.println("Congratulation, you are right.");
}else {
System.out.print("You are WRONG,the result is "+result);
}
}
private boolean isOperator (String token)
{
return ( token.equals("+") || token.equals("-") ||
token.equals("X") || token.equals("/") );
}
//计算用
private int evalSingleOp (char operation, int op1, int op2)
{
int result = 0;
switch (operation)
{
case ADD:
result = op1 + op2;
break;
case SUBTRACT:
result = op1 - op2;
break;
case MULTIPLY:
result = op1 * op2;
break;
case DIVIDE:
result = op1 / op2;
}
return result;
}
}
- 出题和计算都有了,然后就要有判断,在项目中,我们写了一个judge的方法。通过比对用户写的与计算得出的进行比较判断。
整数/多运算符(题目生成/题目运算判题)
扩展需求
- 对于题目生成和判题,我们设计了一个难度划分,从一级到五级,对于用户来说,二到六个数的运算在合理的范围内,但并不说明这个程序限制在六个数的四则运算,稍作修改能提供若干个数的四则运算。
PSP记录
Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|
计划 | 20 | 40 |
·估计耗时 | 20 | 40 |
开发 | 435 | 525 |
·需求分析 | 30 | 50 |
·生成设计文档 | 20 | 30 |
·具体设计 | 30 | 50 |
·具体编码 | 300 | 320 |
·代码复审 | 30 | 15 |
·测试 | 25 | 60 |
报告 | 105 | 110 |
·测试报告 | 50 | 80 |
·事后总结,并提出过程改进计划 | 35 | 20 |
·分析下一步计划 | 20 | 10 |
合计 | 460 | 675 |
结队伙伴:20162315马军