# 20162325 结对编程项目-四则运算 整体总结

## 一、需求分析

• 支持多运算符
• 支持真分数
• 用户可选择生成题目的等级
• 处理生成题目并输出到文件
• 完成题目后从文件读入并判题

UML类图

## 三、实现过程中的关键代码

• 支持真分数
package Arithmetic;

/**
* Created by Administrator on 2017/5/15.
*/
//********************************************************************
//  RationalNumber.java       Java Foundations
//
//  Represents one rational number with a numerator and denominator.
//********************************************************************

public class RationalNumber
{
private int numerator, denominator;

//-----------------------------------------------------------------
//  Constructor: Sets up the rational number by ensuring a nonzero
//  denominator and making only the numerator signed.
//-----------------------------------------------------------------
public RationalNumber (int numer, int denom)
{
if (denom == 0)
denom = 1;

// Make the numerator "store" the sign
if (denom < 0)
{
numer = numer * -1;
denom = denom * -1;
}

numerator = numer;
denominator = denom;

reduce();
}

//-----------------------------------------------------------------
//  Returns the numerator of this rational number.
//-----------------------------------------------------------------
public int getNumerator ()
{
return numerator;
}

//-----------------------------------------------------------------
//  Returns the denominator of this rational number.
//-----------------------------------------------------------------
public int getDenominator ()
{
return denominator;
}

//-----------------------------------------------------------------
//  Returns the reciprocal of this rational number.
//-----------------------------------------------------------------
public RationalNumber reciprocal ()
{
return new RationalNumber (denominator, numerator);
}

//-----------------------------------------------------------------
//  Adds this rational number to the one passed as a parameter.
//  A common denominator is found by multiplying the individual
//  denominators.
//-----------------------------------------------------------------
{
int commonDenominator = denominator * op2.getDenominator();
int numerator1 = numerator * op2.getDenominator();
int numerator2 = op2.getNumerator() * denominator;
int sum = numerator1 + numerator2;

return new RationalNumber (sum, commonDenominator);
}

//-----------------------------------------------------------------
//  Subtracts the rational number passed as a parameter from this
//  rational number.
//-----------------------------------------------------------------
public RationalNumber subtract (RationalNumber op2)
{
int commonDenominator = denominator * op2.getDenominator();
int numerator1 = numerator * op2.getDenominator();
int numerator2 = op2.getNumerator() * denominator;
int difference = numerator1 - numerator2;

return new RationalNumber (difference, commonDenominator);
}

//-----------------------------------------------------------------
//  Multiplies this rational number by the one passed as a
//  parameter.
//-----------------------------------------------------------------
public RationalNumber multiply (RationalNumber op2)
{
int numer = numerator * op2.getNumerator();
int denom = denominator * op2.getDenominator();

return new RationalNumber (numer, denom);
}

//-----------------------------------------------------------------
//  Divides this rational number by the one passed as a parameter
//  by multiplying by the reciprocal of the second rational.
//-----------------------------------------------------------------
public RationalNumber divide (RationalNumber op2)
{
return multiply (op2.reciprocal());
}

//-----------------------------------------------------------------
//  Determines if this rational number is equal to the one passed
//  as a parameter.  Assumes they are both reduced.
//-----------------------------------------------------------------
public boolean isLike (RationalNumber op2)
{
return ( numerator == op2.getNumerator() &&
denominator == op2.getDenominator() );
}

//-----------------------------------------------------------------
//  Returns this rational number as a string.
//-----------------------------------------------------------------
public String toString ()
{
String result;

if (numerator == 0)
result = "0";
else
if (denominator == 1)
result = numerator + "";
else
result = numerator + "/" + denominator;

return result;
}

//-----------------------------------------------------------------
//  Reduces this rational number by dividing both the numerator
//  and the denominator by their greatest common divisor.
//-----------------------------------------------------------------
private void reduce ()
{
if (numerator != 0)
{
int common = gcd (Math.abs(numerator), denominator);

numerator = numerator / common;
denominator = denominator / common;
}
}

//-----------------------------------------------------------------
//  Computes and returns the greatest common divisor of the two
//  positive parameters. Uses Euclid's algorithm.
//-----------------------------------------------------------------
private int gcd (int num1, int num2)
{
while (num1 != num2)
if (num1 > num2)
num1 = num1 - num2;
else
num2 = num2 - num1;

return num1;
}
}



 private String  getA() {
a = String.valueOf(rnd1.nextInt(10) + 1);
return a;
}

 private RationalNumber getB(){
while (true) {
c = rnd1.nextInt(10) + 1;
d = rnd2.nextInt(10) + 1;
b = new RationalNumber(c, d);
if (c < d){
break;
}
}


A是一个随机整数，把它的范围设为1~10，B是一个随机真分数。而每一个操作数既可能为整数，也可能为真分数

public String getOp1(){
if (rnd3.nextInt(2) == 0){
op1 = getA();
}
else
op1 = getB().toString();
return op1;
}

 public String getOp2(){
if (rnd3.nextInt(2) == 0){
op2 = getA();
}
else
op2 = getB().toString();
return op2;
}


• 支持多运算符
 public String getExper(int i){
expr = opd.getOp1() + getOperator();
for (int j = 0; j < i-1; j++) {
String s = opd.getOp1() + getOperator();
expr += s;
}
expr = expr + opd.getOp2();
return expr;
}


• 处理生成题目并输出到文件
package Arithmetic;

import java.io.*;

/**
* Created by Administrator on 2017/5/19.
*/
public class IOFile {
PrintStream  ps;

public IOFile(String file){
try {
ps = new PrintStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

public void WriteQuestionsToFile(String s){
ps.append(s);// 在已有的基础上添加字符串
}
}


• 完成题目后从文件读入并判题
 public static void main(String[] args) throws IOException{
Judgement jdg = new Judgement();
NifixToSuffix nts = new NifixToSuffix();
NumberFormat fmt = NumberFormat.getPercentInstance();
FileInputStream fis = new FileInputStream("Exercises.txt");
StringTokenizer tokenizer1 = null, tokenizer2 = null;
String token1, token2, token3, token4;
String s1 = null;
String str;
int q = 0, count = 0;
IOFile iof = new IOFile("ExercisesResult.txt");
while ((str = in.readLine()) != null) {
tokenizer1 = new StringTokenizer(str, ":");
token1 = tokenizer1.nextToken();
token2 = tokenizer1.nextToken();
tokenizer2 = new StringTokenizer(token2, "=");
token3 = tokenizer2.nextToken();
token4 = tokenizer2.nextToken();
nts.conversion(token3);
if (token4.equals(jdg.evaluate(nts.getMessage()))) {
s1 = "正确！";
q++;
} else {
s1 = "错误，正确答案为：" + jdg.evaluate(nts.getMessage());
}

String s2 = str + "\n" + s1 + "\n\n";
iof.WriteQuestionsToFile(s2);
count++;
}

double accuracy = (double) q / count;
String s3 = "完成" + count + "道题目，答对" + q + "道题，正确率为" + fmt.format(accuracy);
iof.WriteQuestionsToFile(s3);

}


• 实现分数的运算

RationalNumber类。定义好加减乘除四种方法。在栈中进行计算时，每取出一个操作数，先将其转化为RationalNumber类型。具体转化方法如下

public RationalNumber tranIntoRationalNum (String s){
String token1, token2;

StringTokenizer tokenizer1 = new StringTokenizer(s, "/");
token1 = tokenizer1.nextToken();
if (tokenizer1.hasMoreTokens()) {
token2 = tokenizer1.nextToken();
r = new RationalNumber(Integer.parseInt(token1), Integer.parseInt(token2));
}
else {
r = new RationalNumber(Integer.parseInt(token1),1);
}
return r;
}


private String evalSingleOp (char operation, RationalNumber op1, RationalNumber op2)
{
RationalNumber result = new RationalNumber(0,1);

switch (operation)
{
break;
case SUBTRACT:
result = r1.subtract(r2);
break;
case MULTIPLY:
result = r1.multiply(r2);
break;
case DIVIDE:
result = r1.divide(r2);
}

return result.toString();
}


## 四、测试方法

• CalculatorTest

• NifixToSuffixTest

• RationalNumberTest

## 七、遇到的困难及解决方法

• 问题1

• 解决办法

 public String getExper(int i){
//用循环的方法来获取多运算符

for (int j = 0; j < i; j++) {
String s = opd.getOp1() + getOperator();
expr += s;
}
expr = expr + opd.getOp2();
return expr;
}


 public String getExper(int i){
//用循环的方法来获取多运算符
expr = opd.getOp1() + getOperator();
for (int j = 0; j < i-1; j++) {
String s = opd.getOp1() + getOperator();
expr += s;
}
expr = expr + opd.getOp2();
return expr;
}


## 九、参考或引用的设计、实现

• RationalNumber

## 十、PSP

PSP2.1 Personal Software Process Stages 预估耗时（小时） 实际耗时（小时）
Planning 计划
· Estimate · 估计这个任务需要多少时间 0.5 0.5
Development 开发
· Analysis · 需求分析 (包括学习新技术) 2 4
· Design Spec · 生成设计文档 1.5 1
· Design Review · 设计复审 (和同事审核设计文档) 1 1
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 0.5 1
· Design · 具体设计 2 3
· Coding · 具体编码 6 8
· Code Review · 代码复审 2 2.5
· Test · 测试（自我测试，修改代码，提交修改） 2 2.5
Reporting 报告
· Test Report · 测试报告 1 1.5
· Size Measurement · 计算工作量 0.5 0.5
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 0.5 0.5

posted @ 2017-05-21 21:36  20162325金立清  阅读(261)  评论(2编辑  收藏