软件工程个人作业02

这周比上周的要求增多:

程序设计思想:

1.根据学生所处的年级不同,设置了不同难度的题目:二年级,三年级,四年级,可以根据小朋友所处的年级选择相应的题目;

2.根据出题的难度,随机数确定运算式包含的参数个数,随机数确定符号,参数个数比运算符号多一个,生成题目;

3.将题目传给栈,由栈计算结果,并返回结果;

4.获取输入的答案,比对正确答案,可以输出错误的题目,并且计算正确率。

1.1二年级题目:

  1 class TwoGrade{
  2 //难度为小学二年级
  3     
  4     /** 
  5      *1.可以实现2-3个参数的两位数的加减法
  6      *2.可以实现一位数的乘法
  7      *3.可以实现整除,无余数 **/
  8     Random ra=new Random();
  9     
 10     public question count(){//随机出题函数
 11         String[] c={"+","-"};//加减运算符
 12         String[] cc={"*","/"};//乘除运算符
 13         
 14         String s="";//设定返回的字符串
 15         String sss="";//将除号变为÷
 16         String answer="";//设定返回的答案
 17                 
 18         question q=new question();//设定问题类
 19 
 20         int jjorcc=ra.nextInt(3);
 21         switch(jjorcc){//选择加法或者减法
 22         case 0:{//加减法
 23             int num=ra.nextInt(3)+2;//参数的个数;
 24             int[] arr=new int[num];//保存参数
 25             
 26             for(int i=0;i<num;i++){//随机取100以内的数
 27                 arr[i]=ra.nextInt(100);
 28             }
 29             s+=arr[0];
 30             
 31             for(int i=1;i<num;i++)//设定题目
 32             {
 33                 int jorji=ra.nextInt(2);
 34                 s+=c[jorji];
 35                 s+=arr[i];
 36             }
 37             sss=s;
 38             
 39             break;    
 40         }
 41         case 1:{//支持乘法
 42             int[] brr=new int[2];
 43             brr[0]=ra.nextInt(10);
 44             brr[1]=ra.nextInt(10);
 45             
 46             s=brr[0]+"*"+brr[1];
 47             sss=s;
 48         }
 49         break;
 50         case 2:{//支持除法
 51             int[] crr=new int[2];
 52             crr[0]=ra.nextInt(10)+0;
 53             crr[1]=ra.nextInt(10)+1;
 54             int answer1=crr[0]*crr[1];
 55             
 56             s=answer1+"/"+crr[1];
 57             sss=answer1+"÷"+crr[1];
 58         }break;
 59         }
 60         
 61         stack ss=new stack();//引用栈函数,将题目进行运算,并返回结果
 62         answer=ss.ceshi(s);  
 63         q.set_s(sss);
 64         double answer1=Double.parseDouble(answer);
 65         q.set_answer(answer1);
 66         return q;
 67     }
 68     
 69     
 70     @SuppressWarnings("unchecked")
 71     public void print(){
 72         System.out.println("请输入答题的数量:");//设定答题数量
 73         Scanner sc=new Scanner(System.in);
 74         int num=sc.nextInt();
 75         
 76         Vector v=new Vector();//设定存储的错题题目
 77         for(int i=0;i<num;i++){//输出问题,接收答案,判断正误
 78             question q=new question();
 79             q=count();
 80             if(q.get_answer()<0){
 81                  while(true){
 82                         if(q.get_answer()>=0)break;
 83                         q=count();
 84                  }
 85                 System.out.print("("+(i+1)+")"+q.get_s()+"=");
 86                 double answer =sc.nextDouble();
 87                 if(q.get_answer()!=answer){v.addElement(i+1);}
 88             }
 89             else{
 90                 System.out.print("("+(i+1)+")"+q.get_s()+"=");
 91                 double answer =sc.nextDouble();
 92                 //if(q.get_yushu().equals(null)){
 93                     if(q.get_answer()!=answer){v.addElement(i+1);}
 94                 //}
 95                 //else{
 96                     //if((q.get_answer()!=answer)){v.addElement(i+1);}
 97                 //}
 98                 //若该题错误,保存题号
 99             }
100         }
101         
102         //输出结果
103         for(int i=0;i<v.size();i++){
104             System.out.print("("+v.elementAt(i)+")");
105         }
106         
107         if(v.size()==0){
108             System.out.println("恭喜你,全答对啦!");
109         }
110         else{
111             System.out.println("道题是错的。");
112             double rightRate=v.size()/num;
113             System.out.println("正确率为:"+(1-rightRate)*100+"%");
114         }
115     }
116 }
View Code

1.2程序截图

1)可以实现100以内的加减的二至三个参数个数随机的运算,减法无负数

2)可以实现10以内的乘除的两个参数运算,除法无余数

1.3设计思路

用随机数确定加减的运算数,根据随机数确定加减法还是乘除法,比对输入的结果:若结果正确则不输出,结果错误记录题号 ,输出。

查了小学课本,小学二年级的数学题基本实现,只要根据小朋友的年级就可以出对应的题目。

2.1三年级题目

  1 class ThreeGrade{//难度为小学三年级
  2     /** 
  3      * 1.可以实现2-5个参数的万以内的加减法
  4      * 2.可以实现两位数的乘法,除数为一位的除法,结果可有余数
  5      **/
  6     static Random ra=new Random();
  7     
  8     public static question count(){ //出题函数
  9             
 10     String[] c={"+","-"};//加减运算符
 11     String[] cc={"*","/"};//乘除运算符
 12     
 13     String s="";//设定返回的字符串
 14     String sss="";//将除号改为"÷"
 15     String answer="";//设定返回的答案
 16     int yuyuyu=0;//记录除法的被除数
 17             
 18     question q=new question();//设定问题类
 19 
 20     int jjorcc=ra.nextInt(3);
 21     switch(jjorcc){//选择加法或者减法
 22     case 0:{//加减法
 23         int num=ra.nextInt(5)+2;//参数的个数;
 24         int[] arr=new int[num];//保存参数
 25         
 26         for(int i=0;i<num;i++){//随机取10000以内的数
 27             arr[i]=ra.nextInt(10000);
 28         }
 29         s+=arr[0];
 30         
 31         for(int i=1;i<num;i++)//设定题目
 32         {
 33             int jorji=ra.nextInt(2);
 34             s+=c[jorji];
 35             s+=arr[i];
 36         }
 37         
 38         sss=s;
 39         break;    
 40     }
 41     case 1:{//支持乘法
 42         int[] brr=new int[2];
 43         brr[0]=ra.nextInt(10);
 44         brr[1]=ra.nextInt(10);
 45         
 46         s=brr[0]+"*"+brr[1];
 47         
 48         sss=s;
 49     }
 50     break;
 51     case 2:{//支持除法
 52         int[] crr=new int[2];
 53         crr[0]=ra.nextInt(100);
 54         crr[1]=ra.nextInt(10)+1;
 55         yuyuyu=crr[0]%crr[1];
 56         
 57         s=crr[0]+"/"+crr[1];
 58         sss=crr[0]+"÷"+crr[1];
 59     }break;
 60     }
 61     
 62     stack ss=new stack();//引用栈函数,将题目进行运算,并返回结果
 63     answer=ss.ceshi(s);  
 64     q.set_s(sss);
 65     double answer1=Double.parseDouble(answer);
 66     if(yuyuyu==0){}
 67     else{String yu="余数为"+yuyuyu;q.set_yushu(yu);}
 68     
 69     return q;
 70     }
 71     
 72     public void print(){//界面函数
 73         System.out.println("请输入答题的数量:");//设定答题数量
 74         System.out.println("注:若整除不尽,格式为(商 余数为余)");//设定答题数量
 75 
 76         Scanner sc=new Scanner(System.in);
 77         int num=sc.nextInt();
 78         
 79         Vector v=new Vector();//设定存储的错题题目
 80         for(int i=0;i<num;i++){//输出问题,接收答案,判断正误
 81             question q=new question();
 82             q=count();
 83             if(q.get_answer()<0){
 84                  while(true){
 85                         if(q.get_answer()>=0)break;
 86                         q=count();
 87                  }
 88                 System.out.print("("+(i+1)+")"+q.get_s()+"=");
 89                 int answer =sc.nextInt();
 90                 if(q.get_answer()!=answer){v.addElement(i+1);}
 91             }
 92             else{
 93                 System.out.print("("+(i+1)+")"+q.get_s()+"=");
 94                 int answer =sc.nextInt();
 95                 if(q.get_yushu().equals("")){//如果没有余数
 96                     if(q.get_answer()==answer){}
 97                     else{v.addElement(i+1);}
 98                 }
 99                 else{//如果有余数
100                     String yu=sc.next();
101                     if(q.get_answer()==answer&&q.get_yushu().equals(yu)){}
102                     else{v.addElement(i+1);}
103                 }
104                 }
105         }
106         
107         //输出结果
108         for(int i=0;i<v.size();i++){
109             System.out.print("("+v.elementAt(i)+")");
110         }
111         
112         if(v.size()==0){
113             System.out.println("恭喜你,全答对啦!");
114         }
115         else{
116             System.out.println("道题是错的。");
117             double rightRate=v.size()/num;
118             System.out.println("正确率为:"+(1-rightRate)*100+"%");
119         }
120     }
121 }
View Code

2.2程序截图

1)可以实现10000以内的加减的二至五个参数个数随机的运算,减法无负数

2)可以实现100以内的乘除的两个参数运算,除法有余数,要写出来

 

2.3设计思路

用随机数确定加减的运算数,根据随机数确定加减法还是乘除法,比对输入的结果,若有余数则输入余数(以字符串形式保存):若结果正确则不输出,结果错误记录题号 ,输出。

查了小学课本,小学三年级的数学题基本实现,只要根据小朋友的年级就可以出对应的题目。

3.1四年级题目

 1 ass FenShu {
 2     private int denominator,numerator;
 3 
 4     public int getDenominator() {
 5         return denominator;
 6     }
 7 
 8     public void setDenominator(int denominator) {
 9         this.denominator = denominator;
10     }
11 
12     public int getNumerator() {
13         return numerator;
14     }
15 
16     public void setNumerator(int numerator) {
17         this.numerator = numerator;
18     }
19 
20     public FenShu(int denominator, int numerator) {
21         this.denominator = denominator;
22         this.numerator = numerator;
23         yueJian();
24     }
25     
26     FenShu(){}
27     
28     //约简
29     public void yueJian(){
30         int y = 1;
31         for(int i = numerator;i > 1;i--){
32             if(numerator % i == 0 && denominator % i == 0){
33                 y = i;
34                 break;
35             }
36         }
37             numerator /= y;
38             denominator /= y;
39         
40     }
41     
42     //
43     public FenShu add(FenShu b){
44         FenShu c = null;
45         int nNumerator = this.numerator * b.getDenominator() + this.denominator * b.getNumerator();
46         int nDenominator = this.denominator * b.getDenominator();
47         c = new FenShu(nDenominator,nNumerator);
48         return c;
49     }
50     
51     //
52     public FenShu subtract(FenShu b){
53         FenShu c = null;
54         int nNumerator = this.numerator * b.getDenominator() - this.denominator * b.getNumerator();
55         int nDenominator = this.denominator * b.getDenominator();
56         c = new FenShu(nDenominator,nNumerator);
57         return c;
58     }
59     
60     //
61     public FenShu multiply(FenShu b){
62         FenShu c = null;
63         int nNumerator = this.numerator * b.getNumerator();
64         int nDenominator = this.denominator * b.getDenominator();
65         c = new FenShu(nDenominator,nNumerator);
66         return c;
67     }
68     
69     //
70     public FenShu divide(FenShu b){
71         FenShu c = null;
72         int nNumerator = this.numerator * b.getDenominator();
73         int nDenominator = this.denominator * b.getNumerator();
74         c = new FenShu(nDenominator,nNumerator);
75         return c;
76     }
77     
78     //输出分数形式
79     public String toString(){
80         if(numerator != 0){
81 //            if(numerator % denominator == 0)
82 //                return "" + numerator / denominator;
83             return numerator + "/" + denominator;
84         }
85         return "0";
86     }
87     
88 }
View Code
  1 class FourGrade
  2 {
  3     static Random ra=new Random();
  4 
  5     public void print(){
  6       // TODO Auto-generated method stub
  7       Scanner scan = new Scanner(System.in);
  8       System.out.println("是否有括号(1有,0没有)");
  9       int hasKuoHao = scan.nextInt();
 10       System.out.println("加减有无负数(1有,0没有)");
 11       int hasFuShu = scan.nextInt();
 12       System.out.println("除法有无余数(1有,0没有)");
 13       int hasYuShu = scan.nextInt();
 14       System.out.println("数值范围(最大数)");
 15       int maxNum = scan.nextInt();
 16       
 17       int n = ra.nextInt(10)+2;
 18       String[] yunSuanShiArray = createYunSuanShi(hasKuoHao, hasFuShu, hasYuShu, maxNum, n);
 19       for(int i = 0;i < yunSuanShiArray.length;i++){
 20             System.out.println(yunSuanShiArray[i]);
 21       }
 22       scan.close();
 23   }
 24         
 25         
 26         //生成整数计算式添加限制条件,type为运算式类型  0代表整数式,1代表真分数式
 27     public static String[] createYunSuanShi(int hasKuoHao,int hasFuShu,int hasYuShu,int maxNum,int n) {
 28             int i = 0;
 29             int hasChengChu=1;
 30             String yunSuanShiTemp;
 31             String[] yunSuanShiArray = new String[n];
 32             int operatorScope = 2 + 2 * hasChengChu;//运算符范围,2或4,2代表只有加减,4代表有加减乘除
 33             int length;
 34             String[] operatorArray = {"+","-","*","/"};
 35             String[] operatorNum = null;//存储运算数
 36             int num_index;//运算数下标
 37             String[] operatorSymbol = null;//存储运算符
 38             int symbol_index;//运算符下标
 39             int[] brackets = null;//存储括号个数
 40             
 41             while(i < n) {
 42                 length = Integer.parseInt(getOperatorNumber(0, 9)) + 2;//计算式运算数长度
 43                 operatorNum = new String[length];
 44                 operatorSymbol = new String[length - 1];
 45                 num_index = 0;
 46                 symbol_index = 0;
 47                 int type=ra.nextInt(2);
 48                 operatorNum[num_index++] = getOperatorNumber(type, maxNum);//随机生成操作数
 49                 for(int j = 0;j < length - 1;j++){
 50                     operatorSymbol[symbol_index++] = operatorArray[Integer.parseInt(getOperatorNumber(0, operatorScope))];//随机生成操作符
 51                     operatorNum[num_index++] = getOperatorNumber(type, maxNum);//随机生成操作数
 52                 }        
 53                 if(hasKuoHao == 1){
 54                     brackets = randomAddBracket(length);//生成括号数组
 55                 }
 56                 //构造运算式
 57                 yunSuanShiTemp = "";
 58                 for(int j = 0;j < length;j++){
 59                     //添加左括号
 60                     if(hasKuoHao == 1){
 61                         for(int k = 0;k < brackets[j];k++){
 62                             yunSuanShiTemp += "(";
 63                         }
 64                     }
 65                     yunSuanShiTemp += " " + operatorNum[j] + " ";//加上运算数
 66                     
 67                     //添加右括号
 68                     if(hasKuoHao == 1){
 69                         for(int k = 0;k > brackets[j];k--){
 70                             yunSuanShiTemp += ")";
 71                         }
 72                     }
 73                     //如果不是最后一个运算数则要加上运算符
 74                     if(j != length - 1){
 75                         yunSuanShiTemp += operatorSymbol[j];
 76                     }
 77                 }
 78                 
 79                 //计算结果
 80                 String answer = expressCalculate(yunSuanShiTemp, hasFuShu, hasYuShu, type, length - 1);
 81                 if((answer.equals("ERROR"))){
 82                     continue;
 83                 }
 84                 yunSuanShiTemp += "=" + answer;
 85                 //检验重复
 86                 boolean chongFu = false;
 87                 for(int j = 0;j < i;j++){
 88                     if((yunSuanShiArray[j].equals(yunSuanShiTemp))){
 89                         chongFu = true;
 90                         break;
 91                     }
 92                 }
 93                 if(chongFu == false){
 94                     yunSuanShiArray[i++] = yunSuanShiTemp;
 95                 }
 96             }
 97             return yunSuanShiArray;
 98         }
 99         
100         //表达式计算,参数为字符串类型的运算式
101     public static String expressCalculate(String express,int hasFuShu,int hasYuShu,int type,int symbolNum){
102             Stack<String> num = new Stack<String>();
103             Stack<String> symbolS = new Stack<String>();
104             symbolS.push("#");
105             express += "#";
106             char ch;
107             int i = 0;
108             int s = 0;
109             ch = express.charAt(i);
110             while(s < symbolNum){
111                 if(ch == ' '){//读到空格,说明开始读运算数
112                     String readNumStr = "";
113                     while(true){
114                         ch = express.charAt(++i);
115                         if(ch == ' '){
116                             break;
117                         }
118                         readNumStr += ch;
119                         
120                     }
121                     if((i + 1) < express.length()){
122                         ch = express.charAt(++i);
123                     }
124                     num.push(readNumStr);
125                 }else{//读到的是运算符
126                     char compare = priorityCompare(symbolS.peek(),ch + "");
127                     
128                     if(compare == '='){//如果是右括号
129                         symbolS.pop();
130                         ch = express.charAt(++i);
131                     }else if(compare == '>'){//ch的优先级小于栈顶的优先级     比栈顶的优先级高就不算,入栈,低就弹栈运算
132                         //弹出两个运算数,弹出一个运算符
133                         String bStr = num.pop();
134                         String aStr = num.pop();
135                         String symbolT = symbolS.pop();
136                         String c = yunSuan(aStr,bStr,symbolT,hasFuShu,hasYuShu,type);
137                         if(c.equals("ERROR")){
138                             return "ERROR";
139                         }else if(c.indexOf("余") >= 0 && s != symbolNum - 1){//有余数
140                             return "ERROR";
141                         }else{
142                             num.push(c);
143                         }
144                         s++;
145                     }else{
146                         symbolS.push(ch + "");
147                         if((i + 1) < express.length()){
148                             ch = express.charAt(++i);
149                         }
150                     }
151                 
152                 }
153             }
154             return num.pop();
155         }
156         
157     public static String yunSuan(String aStr,String bStr,String symbol,int hasFuShu,int hasYuShu,int type){
158             if(type == 0){//整数
159                 int a = Integer.parseInt(aStr);
160                 int b = Integer.parseInt(bStr);
161                 if(symbol.equals("+")){
162                     return "" + (a + b);
163                 }else if(symbol.equals("-")){
164                     if(a - b < 0 && hasFuShu == 0){
165                         return "ERROR";
166                     }else{
167                         return "" + (a - b);
168                     }
169                 }else if(symbol.equals("*")){
170                     return "" + (a * b);
171                 }else{
172                     if(b == 0){
173                         return "ERROR";
174                     }
175                     if(a % b == 0){
176                         return "" + (a / b);
177                     }else{
178                         if(hasYuShu == 1){
179                             return (a / b) + "余" + (a % b);
180                         }else{
181                             return "ERROR";
182                         }
183                     }
184                 }
185             }else{//分数
186                 String[] af = aStr.split("/");
187                 String[] bf = bStr.split("/");
188                 if(af[0].equals("0") || bf[0].equals("0")){
189                     return "ERROR";
190                 }
191                 FenShu a = new FenShu(Integer.parseInt(af[1]),Integer.parseInt(af[0]));
192                 FenShu b = new FenShu(Integer.parseInt(bf[1]),Integer.parseInt(bf[0]));
193                 if(symbol.equals("+")){
194                     return a.add(b).toString();
195                 }else if(symbol.equals("-")){
196                     FenShu c = a.subtract(b);
197                     if(hasFuShu == 1 && c.getNumerator() < 0){
198                         return "ERROR";
199                     }
200                     return c.toString();
201                 }else if(symbol.equals("*")){
202                     return a.multiply(b).toString();
203                 }else{
204                     return a.divide(b).toString();
205                 }
206             }
207         }    
208         //判断优先级
209     public static char priorityCompare(String a,String b){
210             char[][] priority = {
211                     {'>','>','<','<','<','>','>'},
212                     {'>','>','<','<','<','>','>'},
213                     {'>','>','>','>','<','>','>'},
214                     {'>','>','>','>','<','>','>'},
215                     {'<','<','<','<','<','=','>'},
216                     {'>','>','>','>',' ','>','>'},
217                     {'<','<','<','<','<',' ','='}
218             };
219             int a_index = index_symbol(a);
220             int b_index = index_symbol(b);
221             return priority[a_index][b_index];
222         }
223         
224     public static int index_symbol(String a){
225             String p = "+-*/()#";
226             return p.indexOf(a);
227         }
228         
229         //随机生成括号,参数为运算式的运算数的个数
230     public static int[] randomAddBracket(int length){
231             int[] brackets = new int[length];
232             for(int i = 0;i < brackets.length;i++)   brackets[i] = 0;
233             Random rd = new Random();
234             for(int i = 2;i < length;i++){//添加的括号长度(括号包围的运算数的个数)
235                 for(int j = 0;j < length - i + 1;j++){
236                     int t = rd.nextInt(2);//随机生成0或1,0代表不加括号,1代表加括号
237                     if(t == 1){
238                         if(brackets[j] >= 0 && brackets[j + i - 1] <= 0){//要加的括号的第一个运算数周围没有右括号,且 最后一个运算数周围没有左括号
239                             int counteract = 0;
240                             for(int k = j;k < j + i;k++){//将要加的括号之间的所有运算数对应的brackets相加,
241                                                             //如果和为0说明这个括号之间的括号是匹配的,不会出现括号交叉现象
242                                 counteract += brackets[k];
243                             }
244                             if(counteract == 0){
245                                 brackets[j]++;
246                                 brackets[j + i - 1]--;
247                             }
248                         }
249                     }
250                 }
251             }
252             return brackets;
253         }
254         
255         //随机生成一个运算数( type==0代表生成整数,type==1代表生成真分数,maxNum代表数值范围 0-(maxNum-1)               )
256     public static String getOperatorNumber(int type,int maxNum){
257             Random rd = new Random();
258             int a;
259             while(true){
260                 a = rd.nextInt(maxNum);
261                 if(type == 0){//随机生成一个整数
262                     return "" + a;
263                 }else{//随机生成一个真分数
264                     if(a == 0){
265                         continue;
266                     }
267                     int b = rd.nextInt(a);
268                     FenShu c = new FenShu(a,b);
269                     return c.toString();
270                 }
271             }
272         }
273         
274 }
View Code

3.2程序截图

1)可以实现10000以内的加减的二至十个参数个数随机的运算,减法有负数

2)可以实现100以内的乘除的两个参数运算,除法可以有余数,可以用小数表示

3)可以实现整数的四则运算,可以实现分数的四则运算

4)可以实现小括号的运算

5)可以人为设定题目的类型

3.3设计思路

用随机数确定加减的运算数,根据随机数确定加减法还是乘除法,比对输入的结果,若有余数则输入余数(以字符串形式保存):若结果正确则不输出,结果错误记录题号 ,输出。

1)分数实现,设计分数类,包括:分数的构造,先确定分母,如果分母为0,则再生成一个数直到不为0,在0到分母的范围内随机生成分子;

     分数的加减乘除运算,先实现同分,再进行相应的运算,分数的输出分子分母之间加“/”。

2)括号实现,设运算式长度为n,则可建立一个长度为n的数组名为kuohao,记录每个元素周围的括号情况,0为无括号,正数为左括号,负数为右括号。则可以产生的括号的长度(即括号包围的运算数的个数)为2 ~ (n-1),利用for循环控制括号的长度,循环变量 i 为2 ~ (n - 1),循环体是另一个循环,循环变量 j 为0 ~ (n - i + 1)   (即可以加左括号的运算数的位置),内层循环循环体为:随机生成0或1,1代表加括号,但是还要判断在这是否可以加括号,如果a[j] >=0 (即这个运算数这没有右括号) 且 a[j + i - 1] <= 0(即产生的这个括号的右括号的那个运算数周围没有左括号) 且 sum(a[j] ...... a[j + i - 1]) == 0  (即要加的这个括号之间的括号必须全部匹配,不能因为加上这个括号产生括号交叉现象)变量 j 为0 ~ (n - i + 1)。

编程总结:

1)可以实现根据年级的选择智能出题,少了一些选择,更加方便。

2)括号问题有一部分参考别人的代码,还未能自己实现,需要多加练习。

3)将近花了两个星期的时间,改了删删了改,总有一些自己不满意的地方,下次一定要在写程序之前,勾画好思路,编程也不要莽莽撞撞。

原文地址:https://www.cnblogs.com/gxt-/p/6530113.html