你的位置:首页 > Java教程

[Java教程]现代软件工程_第一周练习_第1题_更新版


主要完成功能:在用户指定最多的运算符个数后,该程序能够随机生成在指定个数以内的四册运算式(包括+,-,*,/,(,),真分数等),在用户输入答案后,程序能够计算随机生成的运算式得到结果,然后与用户输入的结果进行比对,并判断对错与记录用户得分。

界面与运行结果为(在出题时真分数用“()”括起来):

 

 

该项目文件的结构如图:

其中Calculation.java的代码为:

 1 package ljf; 2  3 public class Calculation { 4   //判断是否为数字 5   public static boolean isNumber(char ch){ 6     switch (ch) { 7     case '+':return false; 8     case '-':return false; 9     case '*':return false;10     case '/':return false;11     default:12       return true;13     }14   }15   16   public static Fraction cal(String str){17     Stack<Fraction> stack=new Stack<Fraction>(20);18     FractionCalculation fc=new FractionCalculation();19     String[] array=MidToPosT.Change(str);20     int i=0;21     Fraction fa,fb;22     char op;23     while(!array[i].equals("#")){24       //是数字25       if(isNumber(array[i].charAt(0))){26         //化成分数进栈27         stack.push(new Fraction(Integer.parseInt(array[i++]), 1));28       }else{29         fb=stack.pop();30         fa=stack.pop();31         op=array[i++].charAt(0);32         fa=fc.fraccalculate(fa, op, fb);33         stack.push(fa);34       }35     }36     fa=stack.getTop();37     return fa;38   }39 }

其中Fraction.java的代码为:

 1 package ljf; 2  3 public class Fraction { 4    public int numerator; 5    public int denominator; 6    public Fraction(int numerator, int denominator){ 7     this.numerator=numerator; 8     this.denominator=denominator; 9    }10    public double getRet(){11     return (double)numerator/denominator;12    }13    public String toString(){14     return numerator+"/"+denominator;15    }16    public int getint(){17      return numerator;18    }19 }

其中FractionCalculation.java的代码为:

 1 package ljf; 2  3 import java.util.Scanner; 4 import java.math.*;  5  6 public class FractionCalculation { 7   public char operate(){ 8     int i; 9     char op = ' '; 10     i=(int)(Math.random()*100)%4+1; 11     switch(i){ 12     case 1:op='+';break; 13     case 2:op='-';break; 14     case 3:op='*';break; 15     case 4:op='/'; 16     } 17     return op;   18   } 19    20   public int num(){ 21     int i; 22     i=(int)(Math.random()*100); 23     return i; 24   } 25    26   public void intmatch(){//整数出题 27     int a=this.num(); 28     int b=this.num(); 29     char op=this.operate(); 30     //int answer; 31     String myanswer; 32     System.out.print("请做题:"+a+op+b+"="); 33     String answer1=this.intcalculate(a, op, b); 34     //System.out.print(answer1); 35     Scanner in= new Scanner(System.in);  36     myanswer=in.next(); 37     if(myanswer.equals(answer1)){ 38       System.out.println("恭喜,答案正确。"); 39     } 40     else{ 41       System.out.println("很抱歉,答案错误。正确答案为:"+answer1); 42     } 43   } 44    45   public String intcalculate(int a,char op,int b){//整数之间的计算方法 46     if(op=='+') 47       return (a+b)+""; 48     else if(op=='-') 49       return (a-b)+""; 50     else if(op=='*') 51       return (a*b)+""; 52     else{ 53       int max=this.maxyueshu(a, b); 54       a=a/max; 55       b=b/max; 56       if(b==1){ 57         return a+""; 58       } 59       else{ 60         Fraction t=new Fraction(a,b); 61         String tt=t.toString(); 62         return tt; 63       } 64     }       65   } 66    67  68    69   public int maxyueshu( int a, int b ){ 70     return a%b==0?b:maxyueshu(b,a%b);    71   } 72    73   public Fraction simple(Fraction a){ 74     int max=this.maxyueshu(a.denominator, a.numerator); 75     a.denominator=a.denominator/max; 76     a.numerator=a.numerator/max; 77     return a; 78   } 79    80   81   public Fraction fraccalculate(Fraction a,char op,Fraction b){//分数之间的计算 82     int fenzi,fenmu; 83      84     if(op=='+'){ 85       fenzi=a.denominator*b.numerator+a.numerator*b.denominator; 86       fenmu=a.denominator*b.denominator; 87     }else if(op=='-'){ 88       fenzi=a.numerator*b.denominator-a.denominator*b.numerator; 89       fenmu=a.denominator*b.denominator; 90     }else if(op=='*'){ 91       fenzi=a.numerator*b.numerator; 92       fenmu=a.denominator*b.denominator; 93     }else{ 94       fenzi=a.numerator*b.denominator; 95       fenmu=a.denominator*b.numerator; 96     } 97     if(fenzi*fenmu==0){ 98       return new Fraction(fenzi, fenmu); 99     }else{100       return this.simple(new Fraction(fenzi,fenmu));101     }102     103   }104   105  106   public void frcmatch(){//分数形式b1/a1和b2/a2107     int a1=0,b1=0,a2=0,b2=0;108     char op=' ';109     String myanswer;110     while(b1>=a1){111       a1=this.num()+1;112       b1=this.num();113     }114     Fraction t1=this.simple(new Fraction(a1,b1));115     while(b2>=a2){116       a2=this.num()+1;117       b2=this.num();118     }119     Fraction t2=this.simple(new Fraction(a2,b2));120     op=this.operate();121     if(op=='/'&&t2.numerator==0){//判读第二个分数的分子是否等于0,此时的分数不能执行除法122       this.frcmatch();123     }else{124       System.out.print("请做题:("+t1.toString()+")"+op+"("+t2.toString()+")=");125     }126     Fraction answer=new Fraction(1,1);127     answer=this.fraccalculate(t1, op, t2);128     Scanner in= new Scanner(System.in); 129     myanswer=in.next();130     if(myanswer.equals(answer.toString())){131       System.out.println("恭喜,答案正确。");132     }133     else{134       System.out.println("很抱歉,答案错误。正确答案为:"+answer);135     }136   }137   138   public static void main(String[] args) {139     FractionCalculation a=new FractionCalculation();140     int num;141     for(num=1;num<=100;num++){142       int i=a.num();143       if(i>50)144         a.intmatch();145       else146         a.frcmatch();147     }148   }149 150 }

其中GenerateFormula.java的全部代码为:

 1 package ljf; 2  3 public class GenerateFormula { 4  5   // e := n | e1 + e2 | e1 − e2 | e1 × e2 | e1 ÷ e2 | (e) , 其中e, 6   // e1和e2为表达式,n为自然数或真分数 7   public static int n = 0; 8   public static int nMax = 0; 9   public static int s = 10; 10  11   public static int maxyueshu(int a, int b) { 12     return a % b == 0 ? b : maxyueshu(b, a % b); 13   } 14  15   public static String getTrueFraction() { 16     int i, j;// i分子,j分母,分母要大于分子,要约粉 17     while (true) { 18       i = (int) (Math.random() * 100) % s + 1; 19       j = (int) (Math.random() * 100) % s + 1; 20       if ((j > i) && (j != 1)) { 21         int max = maxyueshu(j, i); 22         i /= max; 23         j /= max; 24         return i + "/" + j; 25       } 26     } 27   } 28  29   public static String fourRan(int pre) { 30     // pre代表上一步的运算符,1+ 2- 3* 4/ 5() 6数 31     n++; 32     int i = (int) (Math.random() * 100) % 6 + 1; 33  34     String str = ""; 35     if (n < nMax) 36       ; 37     else 38       i = 6; 39     switch (i) { 40     case 1: 41       str = fourRan(1) + "+" + fourRan(1); 42       break; 43     case 2: 44       str = fourRan(2) + "-" + fourRan(2); 45       break; 46     case 3: 47       str = fourRan(3) + "*" + fourRan(3); 48       break; 49     case 4: 50       str = fourRan(4) + "/" + fourRan(4); 51       break; 52     case 5: 53       if(pre==5){ 54         str=fourRan(5); 55       }else{ 56       str = "(" + fourRan(5) + ")"; 57       } 58       break; 59     case 6: 60       int temp = (int) (Math.random() * 100) % 2 + 1; 61       if (temp == 1) { 62         // 生成数字返回 63         if (pre == 4) { 64           return (int) (Math.random() * s) + 1 + ""; 65         } else { 66           return (int) (Math.random() * s) + ""; 67         } 68  69       } else { 70         if(pre==5){ 71           return getTrueFraction() ; 72         }else 73         return "(" + getTrueFraction() + ")"; 74  75       } 76     } 77  78     return str; 79   } 80  81   public static String getFormula(int ni, int si) { 82     n=0; 83     nMax = ni; 84     s = si; 85     String str = "", result = ""; 86     int i; 87     i = (int) (Math.random() * 100) % 4 + 1; 88     switch (i) { 89     case 1: 90       str = fourRan(1) + "+" + fourRan(1); 91       break; 92     case 2: 93       str = fourRan(2) + "-" + fourRan(2); 94       break; 95     case 3: 96       str = fourRan(3) + "*" + fourRan(3); 97       break; 98     case 4: 99       str = fourRan(4) + "/" + fourRan(4);100       break;101 102     }103 /*104     // 对生成的式子进行去除多余括号处理105     String[] postfix = MidToPosT.Change(str);106     String[] infix = PostToMid.getInfixByPostfix(postfix);107     for (int in = 0; !infix[in].equals("#"); in++) {108       result = result + infix[in];109     }110     return result;111     */112     return str;113   }114 115 }

其中MidToPosT.java的代码为:

 1 package ljf; 2  3 public class MidToPosT { 4  5   // 定义符号的优先级 6   public static int Precedence(char sign) { 7     switch (sign) { 8     // +、-都为1 9     case '+': 10     case '-': 11       return 1; 12       // *、/为2 13     case '*': 14     case '/': 15       return 2; 16     case '(': 17     case ')': 18     default: 19       return 0; 20     } 21   } 22  23   /**************** 中缀表达式转换成后缀表达式 ********************/ 24   public static String[] Change(String str) { 25     String[] s2 = new String[Test.MAX_RANGE]; 26     // #为结束符 27     String s1 = str + "#"; 28     // 定义大小为20的String类型的栈 29     Stack<Character> T = new Stack<Character>(Test.MAX_RANGE); 30     int i = 0, j = 0; 31     char ch; 32     String temp = " "; 33     T.push('@'); 34     ch = s1.charAt(i); 35     while (ch != '#') { 36       // 遇到'('就进栈 37       if (ch == '(') { 38         T.push(ch); 39         ch = s1.charAt(++i); 40       } else if (ch == ')') { 41         // 遇到')'就把栈中'('后的符号全部出栈 42         while (T.getTop() != '(') 43           s2[j++] = String.valueOf(T.pop()); 44         T.pop(); 45         ch = s1.charAt(++i); 46       } else if (ch == '+' || ch == '-' || ch == '*' || ch == '/') { 47         char w = T.getTop(); 48         while (Precedence(w) >= Precedence(ch)) { 49           s2[j++] = String.valueOf(w); 50           T.pop(); 51           w = T.getTop(); 52         } 53         T.push(ch); 54         ch = s1.charAt(++i); 55       } else { 56         if ((ch >= '0' && ch <= '9') || ch == '.') { 57           int k = i; 58           int flag = 1; 59           int arr = 0; 60           int q = 0;// 记录到下一个位置 61           for (; s1.charAt(i) >= '0' && s1.charAt(i) <= '9'; i++) { 62             if (i == s1.length() - 1) { 63               flag = 0; 64               break; 65             } 66           } 67           if (flag == 1) { 68             q = i; 69             i--; 70             for (int t = k; t <= i; t++) { 71               int single = Integer.parseInt(String.valueOf(s1 72                   .charAt(t))); 73               for (int p = t; p < i; p++) { 74                 single = single * 10; 75               } 76               arr = arr + single; 77             } 78             i = q; 79           } else { 80             q = i; 81             q++; 82             for (int p = k; p <= i; p++) { 83               int single = Integer.parseInt(String.valueOf(s1 84                   .charAt(p))); 85               for (int t = p; t < i; t++) { 86                 single = single * 10; 87               } 88               arr = arr + single; 89             } 90             i = q; 91           } 92  93           s2[j++] = String.valueOf(arr); 94           ch = s1.charAt(i); 95         } 96       } 97     } 98     ch = T.pop(); 99     while (ch != '@') {100       s2[j++] = String.valueOf(ch);101       ch = T.pop();102     }103     s2[j++] = "#";104     return s2;105   }106 107 108 }

其中Stack.java的全部代码为:

 1 package ljf; 2  3 public class Stack<T> { 4   private int top; 5   private T[] stackArray; 6   private int maxSize; 7  8   // 9   public Stack(int maxSize) {10     this.maxSize = maxSize;11     this.top = -1;12     stackArray = (T[])new Object[this.maxSize];13   }14 15   //进栈16   public void push(T push) {17     stackArray[++top] =push;18   }19 20   // 出栈21   public T pop() {22     return stackArray[top--];23   }24 25   // 得到栈顶元素26   public T getTop() {27     return stackArray[top];28   }29 30   // peek the character at index n31   public T peekN(int index) {32     return stackArray[index];33   }34 35   //判断是否为空36   public boolean isEmpty() {37     return (top == -1);38   }39 40   // return stack size41   public int size() {42     return top + 1;43   }44 45 }

其中Test.java的代码为:

 1 package ljf; 2  3 import java.util.Scanner; 4  5 public class Test { 6  7   public static int MAX_RANGE = 40; 8  9   public static void main(String[] args) {10     // TODO Auto-generated method stub11 12     FractionCalculation fCal = new FractionCalculation();13     Scanner sc = new Scanner(System.in);14     System.out.print("输入最多能接受的操作符总数:");15     int n = sc.nextInt();16     System.out.print("输入能接受的最大操作数:");17     int s = sc.nextInt();18     int sum = 0, trueSum = 0;19     char flag = 'y';20     while (flag == 'y') {21       sum++;// 记录做题总数22       String str = GenerateFormula.getFormula(n, s);23       System.out.print(str + "=");24       String userAnswer = sc.next().trim();25       // 判断是否为大于1的真分数26       if (userAnswer.indexOf("'") > 0) {27         String[] array = userAnswer.split("'");28         // 判断是否是负数的输入29         if (array[0].indexOf("-") >= 0) {30           Fraction a = new Fraction(Integer.parseInt(array[0]31               .split("-")[1]), 1);32           Fraction b = new Fraction(Integer.parseInt(array[1]33               .split("/")[0]), Integer.parseInt(array[1]34               .split("/")[1]));35           userAnswer = "-" + fCal.fraccalculate(a, '+', b).numerator36               + "/" + fCal.fraccalculate(a, '+', b).denominator;37         } else {38           Fraction a = new Fraction(Integer.parseInt(array[0]), 1);39           Fraction b = new Fraction(Integer.parseInt(array[1]40               .split("/")[0]), Integer.parseInt(array[1]41               .split("/")[1]));42           userAnswer = fCal.fraccalculate(a, '+', b).numerator + "/"43               + fCal.fraccalculate(a, '+', b).denominator;44         }45       }46       // 化简用户输入的结果47       if (userAnswer.indexOf("/") > 0) {48         if (userAnswer.split("/")[1].equals("1")) {49           userAnswer = userAnswer.split("/")[0];50         }51       }52       // 计算真正的结果并化简53       Fraction fa = Calculation.cal(str.trim());54       if (fa.numerator * fa.denominator < 0) {55         fa.numerator = fa.numerator > 0 ? -fa.numerator : fa.numerator;56         fa.denominator = fa.denominator > 0 ? fa.denominator57             : -fa.denominator;58       }59       String trueAnswer;60       if (fa.denominator == 1) {61         trueAnswer = fa.numerator + "";62       } else {63         if (fa.numerator == 0) {64           trueAnswer = "0";65         } else {66           trueAnswer = fa.numerator + "/" + fa.denominator;67         }68       }69 70       if (trueAnswer.equals(userAnswer)) {71         System.out.println("√");72         trueSum++;73       }74       else {75         System.out.println("×  正确答案是:" + trueAnswer);76       }77 78       System.out.println();79       System.out.print("是否继续(继续y , 退出n):");80       flag = sc.next().charAt(0);81     }82     System.out.println("退出成功! 共做 "+sum+" 道题,做对 "+trueSum+" 道题,做错 "+(sum-trueSum)+" 道题。");83   }84 85 }