先插代码

 1 import java.util.Scanner;
 2 
 3 public class main {
 4     public static void main(String[] args) {
 5         Scanner sc = new Scanner(System.in);
 6         fun f = new fun();
 7 
 8         while (true) {
 9             System.out.println("\t1.生成新题");
10             System.out.println("\t2.重做错题");
11             System.out.println("\t3.退出系统");
12             int choice = sc.nextInt();
13             switch (choice) {
14                 case 1: {
15                     System.out.println("注意:没有重做的错题将会直接消失");
16                     System.out.println("请输入需要生成的题数");
17                     int choice1 = sc.nextInt();
18                     //System.out.println(len);
19                     System.out.println("请输入需要生成的操作数");
20                     int choice2 = sc.nextInt();
21                     //System.out.println(len2);
22                     System.out.println("请输入是否需要加入乘除法,1表示需要,0表示不需要");
23                     int choice3 = sc.nextInt();
24                     System.out.println("请输入是否需要括号,1表示需要,0表示不需要");
25                     int choice4 = sc.nextInt();
26                     System.out.println("请输入操作数的最小范围");
27                     int choice5 = sc.nextInt();
28                     System.out.println("请输入操作数的最大范围");
29                     int choice6 = sc.nextInt();
30 
31                     f = new fun(choice1, choice2, choice3, choice4, choice5, choice6);
32                     f.ff();
33                     break;
34                 }
35                 case 2: {
36                     f.f6();
37                     break;
38                 }
39                 case 3: {
40                     System.exit(0);
41                 }
42             }
43         }
44 
45     }
46 }
  1 import java.util.Random;
  2 import java.util.Scanner;
  3 
  4 public class fun {
  5     public int len1;//打印个数
  6     public int len2;//操作数个数
  7     public int multi;//乘除法
  8     public int paren;//括号
  9     public int leftR;//最小值
 10     public int rightR;//最大值
 11     public int leftP;//左括号
 12     public int rightP;//右括号
 13     public int index;//记录重复生成次数是否过多
 14     double[] a;//存储操作数
 15     int[] b;//存储操作符
 16     String[] jiLu;//记录出现过的题目
 17     double[] result;//记录答案
 18     int[] fault;//记录错题下标
 19     int id;
 20 
 21     public fun() {
 22     }
 23 
 24     public fun(int i1, int i2, int i3, int i4, int i5, int i6) {
 25         this.len1 = i1;
 26         this.len2 = i2;
 27         this.multi = i3;
 28         this.paren = i4;
 29         this.leftR = i5;
 30         this.rightR = i6;
 31         a = new double[len2];//存储操作数
 32         b = new int[len2 - 1];//存储操作符
 33         jiLu = new String[len1];//记录出现过的题目
 34         result = new double[len1];
 35         fault = new int[len1 + 1];
 36         id = 0;
 37     }
 38 
 39     public void ff() {
 40 
 41 
 42         if (this.multi == 1) {
 43             this.multi = 4;
 44         } else {
 45             this.multi = 2;
 46         }
 47 
 48         Random random = new Random();
 49 
 50         int i = 0;
 51         if (this.paren == 1) {
 52             this.paren = len1;
 53         }
 54 
 55         while (i < len1) {
 56             jiLu[i] = "";
 57             String str = "";
 58             for (int j = 0; j < len2 - 1; j++) {//生成操作符
 59                 b[j] = random.nextInt(this.multi);
 60                 jiLu[i] += b[j];
 61             }
 62 
 63             for (int j = 0; j < len2; j++) {//生成操作数
 64                 //System.out.println(j);
 65                 a[j] = random.nextInt(this.rightR - this.leftR + 1) + this.leftR;
 66                 if (j > 0) {
 67                     while (b[j - 1] == 3 && a[j] == 0) {
 68                         //System.out.println("----");
 69                         a[j] = random.nextInt(this.rightR - this.leftR + 1) + this.leftR;
 70                     }
 71                 }
 72                 jiLu[i] += a[j];
 73             }
 74 
 75             if (this.paren != 0) {
 76                 //0+0+0=
 77                 this.leftP = random.nextInt(len2 - 1);//左括号能存在的位置
 78                 jiLu[i] += this.leftP;
 79                 this.rightP = random.nextInt(len2 - this.leftP - 1) + this.leftP + 1;//右括号位置
 80                 jiLu[i] += this.rightP;
 81             }
 82 
 83             int flag = f3(i);//计算是否重复
 84             jiLu[i] = "";
 85             if (flag == 0) {
 86                 int iFlag = 0;
 87                 for (int j = 0; j < len2; j++) {
 88                     if (this.paren >= 1 && this.leftP == j) {
 89                         System.out.print("(");
 90                         jiLu[i] += "(";
 91                     }
 92                     System.out.print((int) a[j]);
 93                     jiLu[i] += (int) a[j];
 94                     if (this.paren >= 1 && this.rightP == j) {
 95                         System.out.print(")");
 96                         jiLu[i] += ")";
 97                         this.paren--;
 98                     }
 99                     if (iFlag != len2 - 1) {
100                         System.out.print(this.f2(b[j]));
101                         jiLu[i] += this.f2(b[j]);
102                     }
103                     iFlag++;
104                 }
105                 System.out.print("=");
106                 jiLu[i] += "=";
107                 f4(i);
108                 if(f5(i)==0){
109                     this.fault[this.id] = i;
110                     this.setId();
111                 }
112                 i++;
113             }
114         }
115     }
116 
117     public void setId() {
118         this.id++;
119     }
120 
121     public int f3(int i) {
122         if (this.index >= len1 * len1) {
123             i = len1;
124             System.out.println("重复生成次数过多,程序自动结束,请检查操作数个数与生成题目之间是否合法");
125         }
126 
127         for (int j = 1; j < i; j++) {
128             if (jiLu[j].equals(jiLu[i])) {
129                 this.index++;
130                 return 1;
131             }
132         }
133         return 0;
134     }
135 
136     public String f2(int i) {
137         if (i == 0) {
138             return "+";
139         } else if (i == 1) {
140             return "-";
141         } else if (i == 2) {
142             return "*";
143         } else {
144             return "/";
145         }
146     }
147 
148     public double f4(int t) {
149         double dR = 0.0;
150         if (this.paren == 0) {//没有括号
151             for (int j = 0; j < len2 - 1; j++) {
152                 if (this.b[j] == 1) {
153                     a[j + 1] = -a[j + 1];
154                 }
155                 if (this.b[j] == 2) {
156                     dR = a[j] * a[j + 1];
157                     a[j] = 0;
158                     a[j + 1] = dR;
159                 }
160                 if (this.b[j] == 3) {
161                     dR = a[j] / a[j + 1];
162                     a[j] = 0;
163                     a[j + 1] = dR;
164                 }
165             }
166 
167             result[t] = 0.0;
168             for (int j = 0; j < len2; j++) {
169                 result[t] += a[j];
170             }
171         } else {
172             //System.out.println("-----");
173             for (int i = this.leftP; i < this.rightP; i++) {//计算括号内
174                 if (this.b[i] == 1) {
175                     a[i + 1] = -a[i + 1];
176                 }
177                 if (this.b[i] == 2) {
178                     dR = a[i] * a[i + 1];
179                     a[i] = 0.0;
180                     a[i + 1] = dR;
181                 }
182                 if (this.b[i] == 3) {
183                     dR = a[i] / a[i + 1];
184                     a[i] = 0;
185                     a[i + 1] = dR;
186                 }
187             }
188             dR = 0.0;
189             for (int j = this.leftP; j < this.rightP + 1; j++) {
190                 dR += a[j];
191             }
192             a[this.leftP] = dR;//括号内计算结果
193 
194             double[] temp = new double[len2 - (this.rightP - this.leftP)];//存去掉括号后的操作数
195             int[] tempB = new int[len2 - (this.rightP - this.leftP) - 1];//存括号外的操作符
196 
197             temp[this.leftP] = dR;
198             if (this.rightP != len2 - 1) {
199                 tempB[this.leftP] = b[this.rightP];
200             }
201 
202             for (int i = 0; i < this.leftP; i++) {
203                 temp[i] = a[i];
204                 tempB[i] = b[i];
205             }
206             for (int i = this.rightP + 1, index = this.leftP + 1; i < len2; i++, index++) {
207                 temp[index] = a[i];
208             }
209             for (int i = this.rightP + 1, index = this.leftP + 1; i < len2 - 1; i++, index++) {
210                 tempB[index] = b[i];
211             }
212 
213             for (int j = 0; j < len2 - (this.rightP - this.leftP) - 1; j++) {
214                 if (tempB[j] == 1) {
215                     temp[j + 1] = -temp[j + 1];
216                 }
217                 if (tempB[j] == 2) {
218                     dR = temp[j] * temp[j + 1];
219                     temp[j] = 0;
220                     temp[j + 1] = dR;
221                 }
222                 if (tempB[j] == 3) {
223                     dR = temp[j] / temp[j + 1];
224                     temp[j] = 0;
225                     temp[j + 1] = dR;
226                 }
227             }
228 
229             result[t] = 0.0;
230             for (int j = 0; j < len2 - (this.rightP - this.leftP); j++) {
231                 result[t] += temp[j];
232             }
233         }
234         return result[t];
235     }
236 
237     public int f5(int i) {
238         Scanner sc = new Scanner(System.in);
239         double d = sc.nextDouble();
240         if ((d - result[i] <= 0.01) && (d - result[i] >= -0.01)) {
241             System.out.println("回答正确");
242             return 1;
243         } else {
244             System.out.print("计算错误,正确答案为:");
245             System.out.println(String.format("%.2f", result[i]));
246             return 0;
247         }
248     }
249 
250     public void f6() {
251         for (int i = 0; i < this.id; i++) {
252             if (this.fault[i] != -1) {
253                 System.out.print(jiLu[this.fault[i]]);
254                 if (f5(this.fault[i]) == 1) {
255                     this.fault[i] = -1;
256                 }
257             }
258         }
259         for (int i = 0; i < this.id; i++) {
260             if (this.fault[i] == -1) {
261                 for (int j = i; j < this.id - 1; j++) {
262                     this.fault[j] = this.fault[j + 1];
263                 }
264                 this.id--;
265             }
266         }
267         System.out.println("错题展示完毕");
268     }
269 }

 

于我个人来说,本题的难度在于题目生成括号的情况下如何计算结果。

计算没有括号的题目十分简单,早先就写好了,但是一直苦于思索带括号的算法;我采用的是将括号内元素优先计算存入预先新建数组,在按括号前,括号后的顺序把其他数也一并存入新数组,最后按照没有括号的算法进行计算