第二次作业

本文介绍了一款支持分数运算、具备计时与打分功能的四则运算器的设计与实现过程。采用Java语言及面向对象技术开发,支持中英文及繁体切换,适用于小学生数学训练。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GitHub地址

https://git.coding.net/songofjoy/softwareProject.git

PSP

PSP2.1

Personal Software Process Stages

预估耗时(分钟)

实际耗时(分钟)

Planning

计划

20

10

·Estimate

· 预估时间

10

10

Development

开发

370

330

·Analysis

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

30

40

·Design Spec

· 生成设计文档

10

30

·Design Review

· 设计复审

20

30

·Coding Standard

· 代码规范

40

30

·Design

· 具体设计

60

100

·Coding

· 具体编码

220

180

·Code Review

· 代码复审

30

40

·Test

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

140

170

Reporting

报告

250

250

·Test Report

· 测试报告

220

220

·Size Measurement

· 计算工作量

20

20

·Postmortem&Process Improvement Plan

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

20

30

合计

 

630

830

需求分析

目标

做一个多功能的四则混合运算器

特性

1.支持分数的四则运算

2.可以实现打分功能

3.计时功能

4.储存历史得分记录

5.实现了中英文繁体的切换

面向用户

主要用于小学生使用,通过这样的一个四则运算工具,可以进行打分测评,可以用来训练计算准确率

假定约束

开发方法:面向对象的开发技术
开发语言:Java
开发期限:1周

需求规定

1.表达式计算:在文本框输入一个表达式,可以返回结果

2.表达式计算判断功能:在文本框输入一个含有=的式子,可以返回是否计算正确

3.中英简繁体转化功能:可以实现java语言的国际化

4.计分功能:可以用来记录历史得分情况

5.计时功能:可以用来计时

6.GUI用户界面:可以更方便的进行用户操作

 

运行环境规定

设备:PC
支持:PC支持Windows操作系统
控制:本软件主要GUI界面运行

详细设计

设计思路

1.将表达式进行数字运算符分离,存入数组

2.通过1中的数组进行一个中缀到逆波兰表达式额转换,运用了双栈来完成

3.分别编写加减乘除等函数

4.根据辗转相除法实现一个求最大公约数、最小公倍数的函数

5.编写判断函数,判断式子是否正确

6.读写文件的函数实现,关闭系统时可以将计算正确率、正确题目等信息保存至文件,下次打开自动调用

7.计时功能、计算正确率统计,中英文繁体转换的函数实现

8.用户交互界面:制作了一个简单的UI界面,使操作更加方便。

 

用户交互界面展示

 

 

 

界面说明

1.右下角是可以实现简体繁体英文的切换。

2.左下角是历史的正确率、正确题目和错误题目,关闭系统数据依然保留。

3.“重置”按钮是使正确率、正确题目和错误题目归0

4.“清除”按钮是使TextField清空。

5.“退格”按钮是使TextField删除末尾的字符。

6.’=’=的区别:

1’=’指在TextField添加一个’=’字符到末尾。

2= 指运算或者判断对错,如果TextField里面没有含=,则计算表达式的结果;如果TextField里面含=,就判断该式子是否正确。

7.“计”实现了计时功能,第一次点击是开始计时,第二此点是停止,第三次点是清0.

 

核心代码说明

 

ComputeController.java 加减乘除计算控制器

package calculator;

 

 

/**

 * 加减乘除计算

 * 冒号:表示一个分数,左边是分子,右边是分母

 *

 * @author Song

 *

 */

public class ComputeController {

 

/**

 * 执行计算

 * @param data1

 * @param data2

 * @param sign

 * @return

 */

public static String exec(String a1,String a2,String sign){

 

String retString="";

switch (sign) {

case "+":retString=add(a1, a2);break;

case "-":retString=substract(a1, a2);break;

case "×":retString=mutiply(a1, a2);break;

case "÷":retString=devide(a1, a2);break;

}

return retString;

 

}

 

/**

 * 是否是加减乘除运算符

 * @param string

 * @return

 */

public static boolean isSign(String string){

 

if(string.equals("+")||string.equals("-")||

string.equals("×")||string.equals("÷")){

return true;

}

return false;

}

/**

 * 求最大公约数

 * @param a1

 * @param a2

 * @return

 */

public static int gcd(int a1,int a2){

 

if(a1==0||a2==0){System.out.println("Error:the data is zero.");}

int min=a1;

int max=a1;

if(a1<a2){

max=a2;

}

else{

min=a2;

}

if(max%min==0){

return min;

}

int temp=max%min;

max=min;

min=temp;

while(max%min!=0){

temp=max%min;

max=min;

min=temp;

}

return min;

}

/**

 * 求最小公倍数

 * @param a1

 * @param a2

 * @return

 */

public static int lcm(int a1,int a2){

 

if(a1==0||a2==0){System.out.println("Error:the data is zero.");}

int gcd=gcd(a1,a2);

 

return a1/gcd*a2;

}

/**

 * stringdata转化为分数的表示形式

 * @param data

 * @return

 */

public static int [] string2fac(String data){

int [] retfac=new int[2];

if(data.contains("/")){

String strings[]=data.split("/");

retfac[0]=Integer.valueOf(strings[0]);

retfac[1]=Integer.valueOf(strings[1]);

}

else{

int integer=Integer.valueOf(data);

retfac[0]=integer;

retfac[1]=1;

}

return retfac;

}

DoubleStack.java 处理计算优先级(双栈和逆波兰表达式)

package calculator;

 

import java.util.ArrayList;

import java.util.Stack;  

 

/**

 * 高级软件工程

 * @author Song

 *

 */

public class DoubleStack {  

 

private ArrayList<String> testString=new ArrayList<>();

    private Stack<String> stack = null;  

    private ArrayList<String> createStrings=new ArrayList<>();

    

    public DoubleStack(String testString) {  

        this.testString = string2array(testString);  

        this.stack = new Stack<String>();  

    }  

    /**

     * 打印逆波兰表达式和

     */

    public void printCreString(){

     System.out.println(createStrings);

    }

    /**

     * 根据逆波兰表达式计算值

     */

    public String compute(){

    

     String ERRORINFO="The Function Is Wrong!";

     try{

         if(createStrings==null||createStrings.size()==0){

         return ERRORINFO;

         }

         while(createStrings.size()!=1){

         int i;

         for(i=0;i<createStrings.size();i++){

         if(ComputeController.isSign(createStrings.get(i))){

         if(i-2<0){return ERRORINFO;}

         String compute=ComputeController.exec(createStrings.get(i-2), createStrings.get(i-1), createStrings.get(i));

         createStrings.set(i-2, compute);

         createStrings.remove(i);

         createStrings.remove(i-1);

         break;

         }

         else if(i==createStrings.size()-1){return ERRORINFO;}

         }

         }

     }

     catch(Exception e){

     return ERRORINFO;

     }

    

     return createStrings.get(0);

    }

    /**

     * 逆波兰 双栈

     */

    public ArrayList<String> analysisString() {  

        for (int i = 0; i < testString.size(); i++) {  

            String c = testString.get(i);  

            if (c.equals("+") || c.equals("-")) {  

                if (stack.isEmpty() || stack.peek().equals("(")) {  

                    stack.push(c);  

                } else {  

                    while (!stack.isEmpty()  

                            && (stack.peek().equals("×") || stack.peek().equals("÷")  

                                    || stack.peek().equals("+") || stack.peek().equals("-"))) {  

                     createStrings.add(stack.pop());

                    }  

                    stack.push(c);  

                }  

            } else if (c.equals("×")|| c.equals("÷")) {  

                if (stack.isEmpty() || stack.peek().equals("+")

                        || stack.peek().equals("-") || stack.peek().equals("(")) {  

                    stack.push(c);  

                } else {  

                    while (!stack.isEmpty()  

                            && (stack.peek().equals("÷") || stack.peek().equals("×"))) {  

                      createStrings.add(stack.pop());

                    }  

                    stack.push(c);  

                }  

            } else if (c.equals("(")) {  

                stack.push(c);  

            } else if (c.equals(")") ){  

                String temp = "";  

                while (!(temp = stack.pop()).equals("(")) {  

                  createStrings.add(temp);

                }  

            } else {  

             createStrings.add(c);

            }  

        }  

        if (!stack.isEmpty()) {  

            while (!stack.isEmpty()) {  

             createStrings.add(stack.pop());

            }  

        }  

        return createStrings;

    }  

    /**

     * stringarray

     * @param input

     * @return

     */

    public static ArrayList<String> string2array(String input){

    

     String curString="";

     ArrayList<String> strings=new ArrayList<>();

     for(int i=0;i<input.length();i++){

     char curchar=input.charAt(i);

     if(curchar<58&&curchar>47||curchar=='/'){curString+=curchar;}

     else{

     if(!curString.equals("")){strings.add(curString);}

     strings.add(""+curchar);curString="";

     }

     }

     if(!curString.equals("")) {strings.add(curString);}

     return strings;

    }

    

  

}  

Frame.java 简易GUI用户界面

package calculator;

 

import java.awt.EventQueue;

 

public class Frame extends JFrame {

 

/**

 *

 */

private static final long serialVersionUID = 1L;

private JPanel contentPane;

private JTextField textField;

 

    JLabel lblNewLabel_1 = new JLabel("0");

JLabel label_2 = new JLabel("0");

JLabel label_3 = new JLabel("0.0%");

 

static JLabel lblNewLabel = new JLabel("正确题目");

static JLabel label = new JLabel("错误题目");

static JLabel label_1 = new JLabel("正确率");

static JButton button_20 = new JButton("重置");

static JButton button_19 = new JButton("清除");

static JButton button_18 = new JButton("退格");

static JButton button_23 = new JButton("简");

static JButton button_21 = new JButton("繁");

static JButton button_22 = new JButton("英");

 

static final String EN="resource_english";

static final String CH="resource_zh_CN_1";

static final String HARD="resource_hard";

 

static Score curScore=new Score();

DecimalFormat df= new DecimalFormat("######0.0");   

 

/**

 * 字体中英繁切换

 * @param resource

 */

public static void changeCharacter(String resource){

 

ResourceBundle rb = ResourceBundle.getBundle(resource);

lblNewLabel.setText(rb.getString("rightAmount"));

label.setText(rb.getString("wrongAmount"));

label_1.setText(rb.getString("radioAmount"));

button_20.setText(rb.getString("reset"));

button_19.setText(rb.getString("clear"));

button_18.setText(rb.getString("back"));

button_23.setText(rb.getString("simply"));

button_21.setText(rb.getString("hard"));

button_22.setText(rb.getString("english"));

 .......

}

 

 

Score.java 评分模型

package calculator;

 

public class Score {

 

private int rightAmount;

private int wrongAmount;

private double radioAmount;

 

public int getRightAmount() {

return rightAmount;

}

public void setRightAmount(int rightAmount) {

this.rightAmount = rightAmount;

}

public int getWrongAmount() {

return wrongAmount;

}

public void setWrongAmount(int wrongAmount) {

this.wrongAmount = wrongAmount;

}

public double getRadioAmount() {

return radioAmount;

}

public void setRadioAmount(double radioAmount) {

this.radioAmount = radioAmount;

}

}

 

Util.java 公共类(文件的读取写入)

package calculator;

 

import java.io.BufferedReader;

import java.io.File;

import java.io.FileInputStream;

import java.io.FileReader;

import java.io.FileWriter;

import java.io.IOException;

import java.io.InputStreamReader;

import java.text.ParseException;

import java.util.Date;

 

 

public class Util {

 

static String FILENAME="score.dat";

public static String SPLITSTRING = "&HHS&";

//创建Score

public static void createScore() throws IOException {

 

Score score=new Score();

 

FileWriter writer = new FileWriter(FILENAME);

writer.write(score.getRightAmount() + SPLITSTRING);

writer.write(score.getWrongAmount() + SPLITSTRING);

writer.write(score.getRadioAmount() + SPLITSTRING);

writer.close();

}

//读取分数

public static Score readScore() throws IOException, ParseException {

 

Score score=new Score();

BufferedReader reader = new BufferedReader(new FileReader(FILENAME));

String line = reader.readLine();

String []infos=line.split(SPLITSTRING);

score.setRightAmount(Integer.valueOf(infos[0]));

score.setWrongAmount(Integer.valueOf(infos[1]));

score.setRadioAmount(Double.valueOf(infos[2]));

 

return score;

 

}

//写分数

public static void saveScore(Score score) throws IOException, ParseException {

 

FileWriter writer = new FileWriter(FILENAME);

writer.write(score.getRightAmount() + SPLITSTRING);

writer.write(score.getWrongAmount() + SPLITSTRING);

writer.write(score.getRadioAmount() + SPLITSTRING);

 

writer.close();

}

 

/**

 *

 * 获取目录下的所有文件名 By Hhs

 */

public static String[] getFileName(String path) {

File file = new File(path);

String[] fileName = file.list();

return fileName;

}

}

 

resource_zh_CN_1.properties等配置文件

 

实现了java语言的国际化,可以实现中文英文简体繁体的切换。

 

项目小结

这个作业功能是实现了,但是有些细节还需要改进,比如当计算结果取=时,如果输入下一个式子,TextField里面的内容不会自动清空,后期可以对这个进行一个优化,加一个字段的判断,如果按下=,该字段置为true,表示下个字符如果是数字就首先把TextField清空再放入数据。

在测试的时候出现一些小bug,比如对负数的处理等等,会得到令人意想不到的结果,当输入的表达式不合法时也加入了一个异常处理,返回The Function is Wrong!给前台界面,后期可以对此做改进,将异常返回做的细一点,比如是分母不能为0或者是数字太大或者是表达式里面有特殊字符,将错误信息尽可能细的返回给用户。

转载于:https://www.cnblogs.com/songofjoy/p/7608912.html

Python 第二次作业中涉及了多个知识点,包括基础的循环结构、数学问题的编程实现,以及函数的应用等。以下是对部分作业内容和解答的详细说明: 1. **斐波那契数列的打印** 作业中有一个题目要求使用 `for` 循环来打印斐波那契数列的前 10 项。初始值为 `a, b = 0, 1`,并且循环执行 10 次,每次打印当前的 `a` 值。正确的代码片段如下: ```python a, b = 0, 1 for _ in range(10): print(a, end=' ') a, b = b, a + b ``` 上述代码中的关键部分是 `a, b = b, a + b`,这一行代码负责更新斐波那契数列的两个相邻值。通过这种方式,可以高效地生成斐波那契数列[^1]。 2. **高次方程求根** 另一个作业题目涉及求解一个五次方程的根。题目提供了一个函数 `f(x)`,其定义为 $ f(x) = x^5 - 15x^4 + 85x^3 - 225x^2 + 274x - 121 $。为了求解该方程在区间 [1.5, 2.4] 内的根,采用了二分法。具体实现如下: ```python def f(x): return x**5 - 15*x**4 + 85*x**3 - 225*x**2 + 274*x - 121 l, r = 1.5, 2.4 k = 0 while k < 20: mid = (l + r) / 2 x = f(mid) if x > 0: l = mid else: r = mid k += 1 print(round(mid, 6)) ``` 在这段代码中,`while` 循环执行了 20 次,每次通过计算中间值 `mid` 来判断根的位置,并逐步缩小搜索范围。最终输出的 `mid` 是近似解,保留了 6 位小数[^2]。 3. **两数之和的查找** 作业还包含了一个经典的算法问题——两数之和。题目要求找到数组中两个数的下标,使得它们的和等于给定的目标值 `target`。该问题可以通过哈希表(字典)来高效解决。具体实现如下: ```python def twoSum(nums, target): dict_ = {} for i in range(len(nums)): m = nums[i] if target - m in dict_: return (dict_[target - m], i) dict_[m] = i nums = [3, 4, 9, 7, 10] target = 11 res = twoSum(nums, target) print(res) ``` 上述代码中,`twoSum` 函数通过遍历数组并使用字典记录已遍历的数值及其下标,从而在后续查找中快速判断是否存在满足条件的配对。最终输出的结果是 `(0, 1)`,表示数组中索引为 0 和 1 的两个数之和等于目标值 11[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值