先插代码
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 }
于我个人来说,本题的难度在于题目生成括号的情况下如何计算结果。
计算没有括号的题目十分简单,早先就写好了,但是一直苦于思索带括号的算法;我采用的是将括号内元素优先计算存入预先新建数组,在按括号前,括号后的顺序把其他数也一并存入新数组,最后按照没有括号的算法进行计算