设计题目
1.小学数学练习
1.1【问题描述】
编写一个帮助小学生练习数学的程序,帮助小学生练习 100 以内的四种数学运算:加、减、乘、除。
1.2【基本要求】
a) 程序应先询问用户的 ID 号(ID 号包括两个大写字母和 4 位数字),例如:
请输入用户 ID 号:AB1234
程序应对输入的 ID 号验证,符合 ID 号要求的格式,然后程序提示三种选择:
(1)开始测试
(2)检查分数
(3)退出
b) 测试:该程序将给出 10 道数学题,例如:
12 * 3 =36
48 + 32 =80
…
56 / 28 =2
注意:
i)学生将依次回答每一个问题(在等于号后面给出答案),然后给出下一道题。
ii)试题应包含四种数学运算:加、减、乘、除,它们是随机产生的。相邻的问题应该是不同的操作,每个操作必须至少出现一次。
iii)为每道题随机生成数字,但必须确保参与运算的数字和结果都小于 100 且大于零的整数,除法时还要注意两个整数要能整除。
iv)十道题做完后,记录学生完成这十道题所用的时间。
v)给每个学生一个分数。将该学生的 ID、成绩和使用时间保存到一个名为 record.txt 的文件中。
vi)在屏幕上输出以下信息:(3 列信息,第 1 列是 b)中的测试题
输出:“问题 | 正确答案 | 你的答案”
c) 成绩检查:从文件“record.txt”中列出该学生的所有历史成绩(其他学生的不显示)。例如:
你以前的记录是:
AB1234 80 150 秒
AB1234 50 182 秒
AB1234 90 98 秒
1.3设计方案
- 文件的输入和输出。
a. 在用户选择开始测试时,将每一次出现的问题,正确答案,以及用户的答案,都要保存到record.txt文件中。并且对这一个过程进行计时。也要输入到文件中
b. 在用户选择检测分数时,要使用文件输出流 将文件中的内容输出来。
c. 在用户选择退出,循环结束。 - 用户名的注册。
使用正则表达式,规范用户名的格式 - 保证四种运算全部出现。
a. 使用集合。声明并初始化一个list
b. 在每次开始测试时,对list中的数字进行乱序。
c. 前4个题 按照list中的数字顺序 选择对应的加减乘除。
d. 剩余的6个题 使用随机数随机生成0123 选择加减乘除。 - 定义四种加减乘除的运算,并确保运算结果大于零小于100。
1.4功能模块划分
- 主方法中,写文件操作。
- 用户名判断方法。
- 生成随机数方法
- 加减乘除方法。
1.5 算法思想
使用面向对象程序设计思想。在main方法中,声明对象,调用方法。封装的思想 写出各个模块方法。
在确保加减乘除的结果不超过100且为整数时,需要有简洁的算法。尽量不要复杂化。
1.6代码实现
package math;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class xiaoxuejisuan {
static Scanner sc = new Scanner(System.in);
static int score;
static long time;
static String[] achievement = new String[11];
static int index = 0; // 记录成绩
static int book; //保存上一次运算,确保下一次运算不重复
static boolean flag = true;
public static void main(String[] args) {
System.out.print("——>请输入用户名:");
String str = sc.next();
while(!judge(str)) {
System.out.print("——>请输入用户名:");
str = sc.next();
}
try {
File file = new File("src\\record.txt");
if(!file.isFile()) {
file.createNewFile();
}
//System.out.print(file.getAbsolutePath());
FileWriter fileWriter = new FileWriter(file, true); //创建一个字符输入流
if(file.length()==0) {
fileWriter.write("你以前的记录是: \n");
}
fileWriter.flush(); //将缓存区里数据全部写入文件
fileWriter.close(); // 关闭输入流
//boolean flag = true;
List<Integer> list = new ArrayList<Integer>(); //对前四次运算 做特殊处理
for(int i = 0;i<4;i++) {
list.add(i);
}
while(flag) {
System.out.print("请选择:\n ——> 1.开始测试 \n ——> 2.检测分数 \n ——> 3.退出");
int choice = sc.nextInt();
switch(choice) {
case 1 : { // 开始测试
score = 0;
book = list.get(3);
long start = System.currentTimeMillis(); //时间开始
Collections.shuffle(list); //对数组乱序
for(int j = 0;j<10;j++) {
if(j<4) {
calculate(list.get(j)); //保证前四次各种运算都出现一次
}else {
calculate();
}
}
long end = System.currentTimeMillis(); //时间结束
time = (end - start)/1000;
fileWriter = new FileWriter(file,true);
fileWriter.write("用户:" + str + " 得分:" + score + " 用时:" + time + "秒\n");
fileWriter.flush();
fileWriter.close();
System.out.println("\n 问题 | 正确答案 | 你的答案");
for(int i = 0;i<10;i++) {
System.out.println(achievement[i]); //输出每次成绩
}
System.out.println();
index = 0; //重置成绩
break;
}
case 2 : { //检测分数
FileReader fr = new FileReader(file);
BufferedReader in = new BufferedReader(fr);
String s ;
while((s = in.readLine())!=null) {
System.out.println(s);
}
System.out.println();
fr.close();
break;
}
case 3 : { //退出
System.out.print("退出成功!");
flag = false;
break;
}
}
}
}catch(Exception e) {
e.printStackTrace();
}
sc.close();
}
//判断用户名是否符合标准
public static boolean judge(String str) {
String regex = "\\p{Upper}\\p{Upper}\\d\\d\\d\\d";
boolean result = str.matches(regex);
if(result) {
System.out.println("用户名正确。赶紧开始练习吧!");
return true;
}else{
System.out.println("你输错啦!用户名的开头两位是大写字母剩余的四位是数字哦");
System.out.println("不再登录用户,按“1”退出!");
if(sc.nextInt()==1) {
System.out.print("退出成功!");
flag = false;
return true;
}
return false;
}
}
public static void calculate() {
int n = (int)(Math.random()*8)%4;//四种运算法随机产生
while(book == n) {
n= (int)(Math.random()*8)%4;
}
book = n ;
switch(n) {
case 0:add();break;
case 1:subtract();break;
case 2:multiplication();break;
case 3:division();break;
}
}
public static void calculate(int n) {
switch(n) {
case 0:add();break;
case 1:subtract();break;
case 2:multiplication();break;
case 3:division();break;
}
}
//加法
public static void add() {
int num1 = (int)(Math.random()*99+1);
int num2 = (int)(Math.random()*(100-num1-1)+1);
System.out.print(num1 + " + " + num2 + " = " );
int result = sc.nextInt();
achievement[index++] = String.format("%-2d + %-2d = | %-2d | %-2d", num1, num2, num1+num2, result);
//字符串格式化。和C语言挺像。
if(result == num1+num2) {
score += 10 ;
}
}
//减法
public static void subtract() {
int num1 = (int)(Math.random()*99+1);
int num2 = (int)(Math.random()*99+1);
if(num1==num2) {
num2 =(int)(Math.random()*99+1);
}
if(num1<num2) {
int temp = num1 ;
num1 = num2;
num2 = temp;
}
System.out.print(num1 + " - " + num2 + " = " );
int result = sc.nextInt();
achievement[index++] = String.format("%-2d - %-2d = | %-2d | %-2d", num1, num2, num1-num2, result);
if(result == num1-num2) {
score += 10;
}
}
//乘法
public static void multiplication() {
int num1 = (int)(Math.random()*99+1);
int num2 = (int)(Math.random()*(100/num1-1)+1); // 确保相乘不超过100
System.out.print(num1 + " * " + num2 + " = ");
int result = sc.nextInt();
achievement[index++] = String.format("%-2d * %-2d = | %-2d | %-2d", num1, num2, num1*num2, result);
if(result == num1*num2) {
score += 10;
}
}
//除法
public static void division() {
int num1 = (int)(Math.random()*99+1);
int num2 = (int)(Math.random()*99+1);
do {
num1 = (int)(Math.random()*99+1);
num2 = (int)(Math.random()*99+1);
}while(!(num1>num2&&num1%num2==0)); //被除数必须比除数大 并且 可以整除
System.out.print(num1 + " / " + num2 + " = ");
int result = sc.nextInt();
achievement[index++] = String.format("%-2d / %-2d = | %-2d | %-2d", num1, num2, num1/num2, result);
if(result == num1/num2) {
score += 10;
}
}
}