一、設計思想:
1.通過Java可視化界面實作對是否有乘除法、是否有負數、是否支援分數以及取值範圍等條件的選擇。
2.将選擇後的真值調用到生成題目的函數中。
3.生成題目的函數中,每個限制條件的子函數通過if語句判斷真值,确定是否進入此子函數。
4.子函數的實作:
取值範圍:分别為生成随機數的上限和下限。
是否有負數:通過生成随機數的奇偶性來判斷是否為負數。
是否有乘除法:若有,則生成随機數對4取餘。否則,對2取餘。
(注:取餘後的值為1、2、3、4分别代表加減乘除)
是否有分數:對分子分母分别去随機值。
(注:若令分數的值在取值範圍内,則分子或分母的值可能過大,極難計算。是以,此處将分子和分母的值控制在取值範圍内)
注:列印方式沒有函數實作。
5.列印題目。
注:用string的二維數組進行記錄每個題目的兩個值和運算符号。每個題目與它之前記錄的所有題目進行比較,如果兩個值和運算符号都相同,則題目重出。
點選“生成題目”按鈕進行題目列印。如果未輸入或未以數字輸入取值範圍和列印數量、輸入的取值下限大于等于上限或者輸入的範圍小于0,則提示重新輸入。
二、源代碼
1 package 四則運算;
2
3 import java.awt.Font;
4 import java.awt.Container;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7
8 import javax.swing.ButtonGroup;
9 import javax.swing.JComboBox;
10 import javax.swing.JLabel;
11 import javax.swing.JButton;
12 import javax.swing.JOptionPane;
13 import javax.swing.JFrame;
14 import javax.swing.JRadioButton;
15 import javax.swing.JScrollPane;
16 import javax.swing.JTextArea;
17 import javax.swing.JTextField;
18
19 public class Main extends JFrame{
20 /**
21 *
22 */
23 private static final long serialVersionUID = 3243154827578985972L;
24
25 public Main(){
26 super("四則運算題目生成器");
27 setResizable(false);
28 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
29 setBounds(100,100,500,400);
30 setVisible(true);
31 setLayout(null);
32 DrawMenu();
33 Update();
34 }
35 // 申請控件變量
36 JLabel cc_Label = new JLabel("是否有乘除法:");
37 ButtonGroup bg1 = new ButtonGroup();
38 JRadioButton cc_RB_Yes = new JRadioButton("有");
39 JRadioButton cc_RB_No = new JRadioButton("無");
40
41 JLabel fu_Label = new JLabel("是否有負數:");
42 ButtonGroup bg2 = new ButtonGroup();
43 JRadioButton fu_RB_Yes = new JRadioButton("有");
44 JRadioButton fu_RB_No = new JRadioButton("無");
45
46 JLabel fen_Label = new JLabel("是否有分數:");
47 ButtonGroup bg3 = new ButtonGroup();
48 JRadioButton fen_RB_Yes = new JRadioButton("有");
49 JRadioButton fen_RB_No = new JRadioButton("無");
50
51 JLabel sz_Label = new JLabel("數值範圍:");
52 JTextField tf1 = new JTextField("0");
53 JLabel xx = new JLabel("~");
54 JTextField tf2 = new JTextField("100");
55
56 JLabel num_JLabel = new JLabel("列印數量:");
57 JTextField num_tf = new JTextField("10");
58 JLabel plan_JLabel = new JLabel("列印方式");
59 public String[] plan_choice = {"1","2","3"};
60 JComboBox plan_cb = new JComboBox(plan_choice);
61 ;
62 Container con = getContentPane();
63 JButton ok_button = new JButton("生成題目");
64
65 // 出題區域
66 JTextArea question_area = new JTextArea();
67 JScrollPane sp = new JScrollPane();
68
69 // 申請數值變量
70 public int num_s = 0,num_b = 0,num_print = 0; // 數值範圍和列印數量
71 public int leftNumber = 0,rightNumber = 0; // 生成題目左右的兩個數
72 public boolean cc_flag = false,fu_flag = false,fen_flag = false; // 對于條件的判斷
73 public int flag = 0; // 用來随機計算運用+ - × ÷
74 public String qt[][] = new String[10000][3];
75 public String leftNumber_string = "",rightNumber_string = "",sign_string = ""; // 将生成題目的數轉換為String類型
76
77 // 更新數值範圍和列印數量
78 public void Update(){
79 num_s = Integer.parseInt(tf1.getText());
80 num_b = Integer.parseInt(tf2.getText());
81 num_print = Integer.parseInt(num_tf.getText());
82 cc_flag = cc_RB_Yes.isSelected();
83 fu_flag = fu_RB_Yes.isSelected();
84 fen_flag = fen_RB_Yes.isSelected();
85 }
86
87 public void DrawMenu(){
88
89 // 添加是否有乘除法内容
90 cc_Label.setBounds(10, 10, 100, 20);
91 cc_RB_Yes.setBounds(100, 10, 40, 20);
92 cc_RB_No.setSelected(true);
93 cc_RB_No.setBounds(140,10,40,20);
94 bg1.add(cc_RB_No);
95 bg1.add(cc_RB_Yes);
96 con.add(cc_Label);
97 con.add(cc_RB_No);
98 con.add(cc_RB_Yes);
99
100 // 添加是否有負數法内容
101 fu_Label.setBounds(10, 50, 100, 20);
102 fu_RB_Yes.setBounds(100, 50, 40, 20);
103 fu_RB_No.setSelected(true);
104 fu_RB_No.setBounds(140,50,40,20);
105 bg2.add(fu_RB_No);
106 bg2.add(fu_RB_Yes);
107 con.add(fu_Label);
108 con.add(fu_RB_No);
109 con.add(fu_RB_Yes);
110
111 // 是否支援分數内容
112 fen_Label.setBounds(10, 90, 100, 20);
113 fen_RB_Yes.setBounds(100, 90, 40, 20);
114 fen_RB_No.setSelected(true);
115 fen_RB_No.setBounds(140,90,40,20);
116 bg3.add(fen_RB_No);
117 bg3.add(fen_RB_Yes);
118 con.add(fen_Label);
119 con.add(fen_RB_No);
120 con.add(fen_RB_Yes);
121
122 // 數值範圍
123 sz_Label.setBounds(10, 130, 100, 20);
124 con.add(sz_Label);
125 tf1.setBounds(100, 130, 30, 20);
126 con.add(tf1);
127 xx.setBounds(140, 130, 20, 20);
128 con.add(xx);
129 tf2.setBounds(160, 130, 30, 20);
130 con.add(tf2);
131
132 // 列印數量
133 num_JLabel.setBounds(10, 170, 100, 20);
134 con.add(num_JLabel);
135 num_tf.setBounds(100, 170, 30, 20);
136 con.add(num_tf);
137
138 // 列印方式
139 plan_JLabel.setBounds(10, 210, 100, 20);
140 plan_cb.setBounds(100,210,100,20);
141 con.add(plan_JLabel);
142 con.add(plan_cb);
143
144 // 生成題目
145 ok_button.setBounds(10, 280, 100, 30);
146 ok_button.addActionListener(new ok_click());
147 con.add(ok_button);
148
149 // 出題區域
150 question_area.setEditable(false);
151 question_area.setLineWrap(true);
152 sp.setViewportView(question_area);
153 sp.setBounds(220, 10, 250, 350);
154 // 設定顯示字型
155 Font font=new Font("宋體",Font.PLAIN,18);
156 question_area.setFont(font);
157 con.add(sp);
158 }
159
160 public void Output(){
161 int f0 = 0,f1 = 0; // 判斷兩個值是否是負數
162 for(int i = 1;i <= num_print;i++){
163 leftNumber_string = "";
164 rightNumber_string = "";
165
166 leftNumber = num_s + (int)(Math.random() * (num_b + 1 - num_s));
167 rightNumber = num_s + (int)(Math.random()*(num_b + 1 - num_s));
168
169 if(fu_flag){ // 如果支援負數,随機生成原來數的負數
170 f0 = (int)(Math.random()*5);
171 if(f0 % 2 == 0 && leftNumber != 0)
172 leftNumber_string = "(-";
173 f1 = (int)(Math.random()*5);
174 if(f1 % 2 == 0 && rightNumber != 0)
175 rightNumber_string = "(-";
176 }
177
178 flag = (int)(Math.random()*100);
179 if(cc_flag) // 如果支援乘除法
180 flag = flag % 4; // 當flag = 0,1,2,3時,分别進行+,-,×,÷
181 else
182 flag = flag % 2;
183
184 switch(flag){
185 case 0: sign_string = "+";break;
186 case 1: sign_string = "-";break;
187 case 2: sign_string = "×";break;
188 case 3: sign_string = "÷";break;
189 }
190
191 if(fen_flag){ // 如果支援分數(注:分數的分子和分母均在取值範圍之内)
192 int leftNumber_up = 0,leftNumber_down = 0,rightNumber_up = 0,rightNumber_down = 0;
193 do{
194 leftNumber_up = num_s + (int)(Math.random()*(num_b + 1 - num_s));
195 leftNumber_down = num_s + (int)(Math.random()*(num_b + 1- num_s));
196 rightNumber_up = num_s + (int)(Math.random()*(num_b + 1 - num_s));
197 rightNumber_down = num_s + (int)(Math.random()*(num_b + 1 - num_s));
198 }while( leftNumber_down == 0 || rightNumber_down == 0 /* || leftNumber_up / leftNumber_down > num_b ||
199 leftNumber_up / leftNumber_down < num_s || rightNumber_up / rightNumber_down > num_b ||
200 rightNumber_up / rightNumber_down < num_s */);
201
202 // 分數約分
203 int temp_min_left = Math.min(leftNumber_up,leftNumber_down);
204 int temp_min_right= Math.min(rightNumber_up,rightNumber_down);
205
206 for(int k = temp_min_left;k >= 2;k--){
207 if(leftNumber_up % k == 0 && leftNumber_down % k == 0){
208 leftNumber_up = leftNumber_up / k;
209 leftNumber_down = leftNumber_down /k;
210 break;
211 }
212 }
213 if(leftNumber_down == 1)
214 leftNumber_string = leftNumber_string + Integer.toString(leftNumber_up);
215 else
216 leftNumber_string = leftNumber_string + Integer.toString(leftNumber_up) + "/" + Integer.toString(leftNumber_down);
217
218 for(int l = temp_min_right;l >= 2;l--){
219 if(rightNumber_up % l == 0 && rightNumber_down % l == 0){
220 rightNumber_up = rightNumber_up / l;
221 rightNumber_down = rightNumber_down / l;
222 break;
223 }
224 }
225 if(rightNumber_down == 1)
226 rightNumber_string = rightNumber_string + Integer.toString(rightNumber_up);
227 else
228 rightNumber_string = rightNumber_string + Integer.toString(rightNumber_up) + "/" + Integer.toString(rightNumber_down);
229
230 }
231 else{ // 如果不支援分數
232 // 将生成的題目記錄為String類型
233 leftNumber_string = leftNumber_string + Integer.toString(leftNumber);
234 rightNumber_string = rightNumber_string + Integer.toString(rightNumber);
235 }
236
237 // 如果是負數添加括号(注:分數無負數)
238 if(f0 % 2 == 0 && fu_flag && leftNumber != 0)
239 leftNumber_string = leftNumber_string + ")";
240 if(f1 % 2 == 0 && fu_flag && rightNumber != 0)
241 rightNumber_string = rightNumber_string + ")";
242
243
244 // 判斷題目是否有問題
245 boolean re = false;
246 for(int j = 1;j < i;j++){
247 // 判斷題目是否重複
248 if(leftNumber_string == qt[j][0] && rightNumber_string == qt[j][1] && sign_string == qt[j][2]){
249 re = true;
250 }
251 // 判斷除數是否為0
252 if(flag == 3 && rightNumber == 0){
253 re = true;
254 }
255 }
256 if(re){
257 i = i - 1;
258 }
259 else{
260 qt[i][0] = leftNumber_string;
261 qt[i][1] = rightNumber_string;
262 qt[i][2] = sign_string;
263 }
264
265 }
266
267 }
268
269
270 public void Print(){
271 for(int i = 1;i <= num_print;i++){
272 question_area.append(qt[i][0] + " " + qt[i][2] + " " + qt[i][1] + " " +"=");
273 question_area.append("\n");
274 }
275
276 }
277
278 public static void main(String args[]){
279 new Main();
280 }
281
282 class ok_click implements ActionListener{
283
284 @Override
285 public void actionPerformed(ActionEvent e) {
286 // TODO 自動生成的方法存根
287 question_area.setText(""); // 重新出題,進行區域清空
288 // 對輸入的值是否規範進行判斷
289 boolean isInt = true;
290 for(int i = 0;i < tf1.getText().length();i++)
291 if(!Character.isDigit(tf1.getText().charAt(i)))
292 isInt = false;
293 for(int i = 0;i < tf2.getText().length();i++)
294 if(!Character.isDigit(tf2.getText().charAt(i)))
295 isInt = false;
296 for(int i = 0;i < num_tf.getText().length();i++)
297 if(!Character.isDigit(num_tf.getText().charAt(i)))
298 isInt = false;
299 // 判斷值是否不是整型,是否為空值,取值是否超出範圍
300 if(tf1.getText().equalsIgnoreCase("") || tf2.getText().equalsIgnoreCase("")||
301 num_tf.getText().equalsIgnoreCase(""))
302 JOptionPane.showMessageDialog(null, "輸入不能有空值,請重新輸入!");
303 else if(isInt == false)
304 JOptionPane.showMessageDialog(null, "輸入必須為數字,請重新輸入!");
305 else if(Integer.parseInt(num_tf.getText()) >= 10000)
306 JOptionPane.showMessageDialog(null, "列印數量過多,請重新輸入!");
307 else if(Integer.parseInt(tf1.getText()) >= Integer.parseInt(tf2.getText()))
308 JOptionPane.showMessageDialog(null, "取值範圍的下限不能大于等于上限,請重新輸入!");
309 else if(Integer.parseInt(tf1.getText()) < 0 || Integer.parseInt(tf2.getText()) < 0)
310 JOptionPane.showMessageDialog(null, "取值範圍不能為負數,請重新輸入!");
311 else{
312 Update();
313 Output();
314 Print();
315 }
316 }
317 }
318 }
三、運作結果
運作界面:

所有條件均滿足時,列印界面:
四、時間記錄日志
日期 | 時間 | 進度 | 淨時 |
3/18 | 13:00~14:00 | 實作初步界面 | 60 |
14:00~15:30 | 實作初步算法 | 90 | |
15:30~17:00 | 算法完善 | ||
19:00~21:00 | 算法完善與界面優化 | 120 |
五、個人總結:
1.做出更加詳細的設計思想,盡量不要摸着石頭過河。
2.靈活運用一些全局變量。