1. 程式人生 > >2016011995 小學四則運算練習軟件項目報告

2016011995 小學四則運算練習軟件項目報告

java 把他 stmp i++ hashmap strong exc 練習題 oid

【coding.net地址】:https://git.coding.net/aspirinone/2016011995week2.git

【測試】在git上clone項目以後,在命令行編譯為class文件,再運行java Main 10

【計劃】項目完成步驟

技術分享圖片

【開發過程】

一、需求分析

(1) 程序可接收一個輸入參數n,然後隨機產生n道加減乘除練習題,每個數字在 0 和 100 之間,運算符在3個到5個之間。

(2) 每個練習題至少要包含2種運算符,而且練習題在運算過程中不得出現負數與非整數,比如不能出 3÷5+2=2.6,2-5+10=7等算式。

二、功能設計

  基本要求:根據需求隨機出題並得出答案。

三、設計實現

(1)Main.java類啟動程序,接收參數n,引用ChuangJian.java

(2) ChuangJian.java類創建一個result.txt文件(如果已有一個txt文件,要事先刪除),輸出學號和題目,引用ChuTi.java類

 1 public class Main {
 2     public static void main(String[] args) {
 3     Scanner input = new Scanner(System.in);
 4     System.out.print("請輸入題目數量:");
 5     int n = 0;
6 try{ 7 n = input.nextInt(); 8 }catch (Exception e){ 9 Scanner in = new Scanner(System.in); 10 System.out.print("輸入有誤,請輸入數字:"); 11 n = in.nextInt(); 12 } 13 ChuangJian.File(n); 14 } 15 }

 1 public class ChuangJian {
 2     public static
void File(int n){ 3 try{ 4 File file = new File("result.txt"); 5 if (file.exists()) { 6 file.delete(); 7 } 8 if(file.createNewFile()){ 9 FileOutputStream txtfile = new FileOutputStream(file); 10 PrintStream p = new PrintStream(txtfile); 11 p.println("2016011995"); 12 for(int i=0;i<n;i++){ 13 p.println(ChuTi.crePro()); 14 } 15 txtfile.close(); 16 p.close(); 17 System.out.println("文件創建成功!"); 18 } 19 } 20 catch(IOException ioe) { 21 ioe.printStackTrace(); 22 } 23 } 24 }

(3)ChuTi.java類中隨機產生3-5個操作符,並隨機產生相應的數字,隨機產生的操作符是通過下標數組確定的:(部分代碼)

1  public static String crePro(){
2         Random random = new Random();
3         String[] operator = {"+","-","×","÷"};
4 
5         int operatorCount = 3+random.nextInt(3); //操作符的個數3-5
6         int[] num = new int[operatorCount+1]; 
7         int[] index = index(operatorCount); //操作符的下標
8         String s = new String();
9 }

 1 private static int[] index(int n){ //產生操作符的下標數組
 2         Random random = new Random();
 3         int similar=0;
 4         int[] a = new int[n];
 5         for(int j=0;j<n;j++){
 6             a[j] = random.nextInt(4);
 7         }
 8         for(int j=1;j<n;j++){
 9             if(a[0]==a[j]) similar++;
10         }
11         if(similar==n-1) return index(n); 
12         else {
13             return a;
14         }
15     }

(4)Jisuan.java類用於判斷運算過程中是否出現負數和小數,使用了調度場算法和逆波蘭表達式,詳見算法詳解部分。

四、算法詳解

在Jisuan.java類中運用了以下思想:

參考了博客《調度場算法與逆波蘭表達式》:https://blog.csdn.net/acdreamers/article/details/46431285

調度場算法規則如下:從左到右遍歷中綴表達式的每個數字和符號,若是數字就輸出,即成為後綴表達式的一部分;若是符號,則判斷其與棧頂符號的優先級,若是右括號或優先級低於棧頂符號,則彈出棧 頂元素並輸出,將當前元素壓入棧,一直到輸出後綴表達式為止。

逆波蘭表達式求值步驟:

*初始化一個空堆棧

*如果字符是一個操作數,把他壓入堆棧

*如果字符是個操作符,彈出兩個操作數,執行恰當操作,然後把結果壓入堆棧,如果不能夠彈出兩個操作數,那麽後綴表達式的語法錯誤

*到後綴表達式末尾,從堆棧中彈出結果,若後綴表達式格式正確,那麽堆棧應該為空

(1)使用HashMap鍵值對規定字符優先級:

1 public static int calculate(String s) {
2         Stack<Integer> stack1 = new Stack<>(); //放數字
3         Stack<String> stack2 = new Stack<>(); //放操作符
4         HashMap<String, Integer> hashmap = new HashMap<>(); //存放運算符優先級
5         hashmap.put("(", 0);
6         hashmap.put("+", 1);
7         hashmap.put("-", 1);
8         hashmap.put("×", 2);
9         hashmap.put("÷", 2);

(2)對字符串中的操作符一個個處理,遇到數字則壓入棧,calculate()函數用於將運算過程中出現負數和小數的情況都返回為負數,後續排除。

 1 switch (c) {
 2                     case ‘=‘: { //遇到等號
 3                         String stmp;
 4                         while (!stack2.isEmpty()) { //當前符號棧裏面還有+ - * /,即還沒有算完
 5                             stmp = stack2.pop();
 6                             int a = stack1.pop();
 7                             int b = stack1.pop();
 8                             int sresulat = calculate(b, a, stmp);
 9                             if(sresulat<0)
10                                 return  -1;
11                             stack1.push(sresulat);
12                         }
13                         break;
14                     }
15 
16                     default: {  //遇到加減乘除等操作符
17                         String stmp;
18                         while (!stack2.isEmpty()) { //如果符號棧有符號
19                             stmp = stack2.pop(); //當前符號棧,棧頂元素
20                             if (hashmap.get(stmp) >= hashmap.get(String.valueOf(c))) { //比較優先級
21                                 int a = stack1.pop();
22                                 int b = stack1.pop();
23                                 int sresulat =calculate (b, a, stmp);
24                                 if(sresulat<0)
25                                     return  -1;
26                                 stack1.push(sresulat);
27                             }
28                             else {
29                                 stack2.push(stmp);
30                                 break;
31                             }
33                         }
34                         stack2.push(String.valueOf(c));  //將符號壓入符號棧
35                         break;
36                     }
37                 }

【測試】

【時間分配】

技術分享圖片

  

2016011995 小學四則運算練習軟件項目報告