JAVA例题之四则运算
题目:四则运算课堂测试
例题要求:
阶段一:定义方法验证题目是否重复;并将出题参数用子方法定义。 2、定义随机数生成器子方法,根据出题参数(出题个数、操作数的个数、确定操作数的取值范围)生成全部的随机操作数。
阶段二:定义方法实现在线答题;全部完成后,显示答题结果,输出正确率和错题。 2、定义方法实现错题集、错题重练并记录错题的次数功能。 阶段三 3、增加倒计时功能,完成定时测试功能。
我这次完成的是阶段三的内容,
要实现倒计时功能,我的想法是可以采用JAVA中的 System.currentTimeMillis() 函数来获取距离 1970-01-01 00:00:00 相差的毫秒数,通过开始是获取一个时间值,再每次作答完成后再获取一个时间值,两者做差在换算成秒即可求出从开始到每一次作答经过的时间差,从而间接的达到了倒计时的功能。
这个方法的缺点是,再程序运行时还是会产生一些误差,还有就是不能实现可视化的倒计时。
下面是主运行类:
import Cal.LT;
import java.util.ArrayList;
import java.util.*;
import java.util.Random;
import java.util.Scanner;
public class newNumber2 {
//主界面
public static void main(String[] args) {
ArrayList<String> errorQuestion = new ArrayList<>();
ArrayList<Integer> errorQuestionTime = new ArrayList<>();
while(true) {
Scanner sc = new Scanner(System.in);
int num1, num2, num3;
System.out.println("请输入出题的个数:");
num1 = sc.nextInt();
System.out.println("请输入操作数的个数:");
num2 = sc.nextInt();
System.out.println("请确定操作数的范围:");
num3 = sc.nextInt();
createNum(num1, num2, num3, errorQuestion, errorQuestionTime);
while (true) {
System.out.println("重新出题请输入1, 练习错题请输入2, 退出请输入3");
int n = sc.nextInt();
if(n == 1) {
break;
}
switch (n) {
case 2:
review(errorQuestion, errorQuestionTime);
break;
case 3:
Sum(errorQuestion, errorQuestionTime);
System.exit(0);
}
}
}
}
//判断出题是否重复
public static int ifSame(ArrayList<String> str4, String s) {
int num = 0;
for (int i = 0; i < str4.size(); i++) {
if(s.equals(str4.get(i))) {
num++;
break;
}
}
if(num == 0) {
str4.add(s);
return 1;
}else {
return 0;
}
}
//出题函数
public static void createNum(int num1, int num2, int num3, ArrayList<String> errorQuestion, ArrayList<Integer> errorQuestionTime) {
Random rand = new Random();
Scanner sc = new Scanner(System.in);
ArrayList<String> st = new ArrayList<>();
int[] NUM = new int[num2];
String[] Fuhao = new String[num2 - 1];
int[] F = new int[num2 - 1];
double sum = 0.0;
System.out.println("答题时间(秒):");
double Time = sc.nextDouble();
long addition = 0;
long change = 0;
long before = System.currentTimeMillis();//获取当前的时间
int judge2 = 0;
for(int i = 0; i < num1; i++) {
for(int j = 0; j < num2; j++) {
NUM[j] = rand.nextInt(num3);
}
for(int k = 0; k < num2 - 1; k++) {
F[k] = rand.nextInt(4);
if(F[k] == 0) {
Fuhao[k] = "+";
}else if(F[k] == 1) {
Fuhao[k] = "-";
}else if(F[k] == 2) {
Fuhao[k] = "*";
}else if(F[k] == 3) {
Fuhao[k] = "/";
}
}
int judge1 = 0;
for(int u = 0; u < num2 - 1; u++) {
if(Fuhao[u] == "/" && NUM[u + 1] == 0) {
judge1 = 1;
}
}
if(judge1 == 1) {
i--;
continue;
}
StringBuffer strB = new StringBuffer();
for(int o = 0; o < num2; o++) {
if(o == num2 - 1) {
strB.append(NUM[o]);
}else {
strB.append(NUM[o]).append(Fuhao[o]);
}
}
if(i == 0) {
st.add(strB.toString());
System.out.println(st.get(i) + "=");
addition = System.currentTimeMillis();
change = before - addition;
judge2 = ifTure(st.get(i), errorQuestion, errorQuestionTime, i, before, change, Time);
if(judge2 == 1) {
sum++;
}else if(judge2 == 3) {
break;
}
}else {
int judge = ifSame(st, strB.toString());
if (judge == 1) {
System.out.println(st.get(i) + "=");
long after = System.currentTimeMillis();
judge2 = ifTure(st.get(i), errorQuestion, errorQuestionTime, i, before, change, Time);
if(judge2 == 1) {
sum++;
}else if(judge2 == 3) {
int su = i+1;
System.out.println("本次答题计划出题" + num1 + "个" + "你以进行了" + su + "道题的作答,但时间已到。");
double acc = sum / (i+1);
System.out.println("在以答的题中正确率为:" + acc);
break;
}else if(judge2 == 4) {
int su = i+1;
System.out.println("本次答题计划出题" + num1 + "个," + "你以进行了" + su + "道题的作答,但时间已到。");
double acc = (++sum) / (num1);
System.out.println("在以答的题中正确率为:" + acc);
break;
}
}
}
}
if(judge2 != 3 ) {
double f = sum / num1;
System.out.println("正确率为:" + f);
}
}
//判断答题是否正确
public static int ifTure(String st, ArrayList<String> errorQuestion, ArrayList<Integer> errorQuestionTime,long j, long Time, long change, double AllTime) {
long newTime = System.currentTimeMillis();
Cal.LT it = new Cal.LT();
Scanner sc = new Scanner(System.in);
double myAn = sc.nextDouble();
List<String> list = it.work(st);
List<String> list2 = it.InfixToPostfix(list);
double an = it.doCal(list2);
double diff = (newTime - Time - change * j) / 1000.0;
if(diff > AllTime && myAn == an) {
System.out.println("虽然回答正确但时间到了");
return 4;
}else if(diff > AllTime && myAn != an) {
errorQuestion.add(st);
int i = 1;
errorQuestionTime.add(i);
System.out.println("回答错误并且时间已到。");
return 3;
} else {
if (myAn == an) {
System.out.println("正确。");
return 1;
} else {
System.out.println("错误。");
errorQuestion.add(st);
int i = 1;
errorQuestionTime.add(i);
return 0;
}
}
}
//复习时判断答题是否正确
public static void ifTure2(String st, ArrayList<String> errorQuestion, ArrayList<Integer> errorQuestionTime) {
Cal.LT it = new LT();
Scanner sc = new Scanner(System.in);
int myAn = sc.nextInt();
List<String> list = it.work(st);
List<String> list2 = it.InfixToPostfix(list);
int an = it.doCal(list2);
if (myAn == an) {
System.out.println("正确。");
}else {
System.out.println("错误。");
int i = errorQuestionTime.get(errorQuestion.indexOf(st));
i++;
errorQuestionTime.set(errorQuestion.indexOf(st), i);
}
}
//复习函数
public static void review(ArrayList<String> errorQuestion, ArrayList<Integer> errorQuestionTime ) {
if(errorQuestion.size() == 0) {
System.out.println("目前没有错题。");
}else {
Scanner sc = new Scanner(System.in);
for (int i = 0; i < errorQuestion.size(); i++) {
System.out.println(errorQuestion.get(i) + "=");
ifTure2(errorQuestion.get(i), errorQuestion, errorQuestionTime);
}
}
}
//统计函数
public static void Sum(ArrayList<String> errorQuestion, ArrayList<Integer> errorQuestionTime) {
for(int m = 0; m < errorQuestion.size(); m++) {
System.out.print(errorQuestion.get(m));
System.out.println(":" + "做错了" + errorQuestionTime.get(m) + "次");
}
}
}
除了主要的执行类我还借鉴了网上的将字符串中的算数式求出结果的类
import java.util.*;
public class LT {
public char[] op = {'+','-','*','/','(',')'};
public String[] strOp = {"+","-","*","/","(",")"};
public boolean isDigit(char c){
if(c>='0'&&c<='9'){
return true;
}
return false;
}
public boolean isOp(char c){
for(int i=0;i<op.length;i++){
if(op[i]==c){
return true;
}
}
return false;
}
public boolean isOp(String s){
for(int i=0;i<strOp.length;i++){
if(strOp[i].equals(s)){
return true;
}
}
return false;
}
/**
* 处理输入的计算式
* @param str
* @return
*/
public List<String> work(String str){
List<String> list = new ArrayList<String>();
char c;
StringBuilder sb = new StringBuilder();
for(int i=0;i<str.length();i++){
c = str.charAt(i);
if(isDigit(c)){
sb.append(c);
}
if(isOp(c)){
if(sb.toString().length()>0){
list.add(sb.toString());
sb.delete(0, sb.toString().length());
}
list.add(c+"");
}
}
if(sb.toString().length()>0){
list.add(sb.toString());
sb.delete(0, sb.toString().length());
}
return list;
}
public void printList(List<String> list){
for(String o:list){
System.out.print(o+" ");
}
}
/**
* 中缀表达式转化为后缀表达式
* 1,遇到数字输出
* 2,遇到高优先级的全部出栈
* 3,最后全部出栈
*/
public List<String> InfixToPostfix(List<String> list){
List<String> Postfixlist = new ArrayList<String>();//存放后缀表达式
Stack<String> stack = new Stack<String>();//暂存操作符
//stack.push('#');
for(int i=0;i<list.size();i++){
String s = list.get(i);
if(s.equals("(")){
stack.push(s);
}else if(s.equals("*")||s.equals("/")){
stack.push(s);
}else if(s.equals("+")||s.equals("-")){
if(!stack.empty()){
while(!(stack.peek().equals("("))){
Postfixlist.add(stack.pop());
if(stack.empty()){
break;
}
}
stack.push(s);
}else{
stack.push(s);
}
}else if(s.equals(")")){
while(!(stack.peek().equals("("))){
Postfixlist.add(stack.pop());
}
stack.pop();
}else{
Postfixlist.add(s);
}
if(i==list.size()-1){
while(!stack.empty()){
Postfixlist.add(stack.pop());
}
}
}
return Postfixlist;
}
/**
* 后缀表达式计算
*/
public int doCal(List<String> list){
Stack<Integer> stack = new Stack<Integer>();
for(int i=0;i<list.size();i++){
String s = list.get(i);
int t=0;
if(!isOp(s)){
t = Integer.parseInt(s);
stack.push(t);
}else{
if(s.equals("+")){
int a1 = stack.pop();
int a2 = stack.pop();
int v = a2+a1;
stack.push(v);
}else if(s.equals("-")){
int a1 = stack.pop();
int a2 = stack.pop();
int v = a2-a1;
stack.push(v);
}else if(s.equals("*")){
int a1 = stack.pop();
int a2 = stack.pop();
int v = a2*a1;
stack.push(v);
}else if(s.equals("/")){
int a1 = stack.pop();
int a2 = stack.pop();
int v = a2/a1;
stack.push(v);
}
}
}
return stack.pop();
}
}
方法实现上整个主程序还很不成熟,也比较繁琐,日后会进一步改进。
浙公网安备 33010602011771号