1. 程式人生 > >130242014027-陳鋒-第2次實驗

130242014027-陳鋒-第2次實驗

get 語言 double tostring sub 獲取 軟件 string 內部

一、實驗目的

1.熟悉體系結構的風格的概念

2.理解和應用管道過濾器型的風格。

3、理解解釋器的原理

4、理解編譯器模型

二、實驗環境

硬件:

軟件:Python或任何一種自己喜歡的語言

三、實驗內容

1、實現“四則運算”的簡易翻譯器。

結果要求:

1)實現加減乘除四則運算,允許同時又多個操作數,如:2+3*5-6 結果是11

2)被操作數為整數,整數可以有多位

3)處理空格

4)輸入錯誤顯示錯誤提示,並返回命令狀態“CALC”

四、實驗步驟:

要求寫具體實現代碼,並根據實際程序,畫出程序的總體體系結構圖和算法結構圖。

import java.util.ArrayList;
import java.util.Scanner;
import java.util.Stack;

public class Main {

public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("輸入字符串");
String b = sc.next();
System.out.println(caculate2(b));

}

// 對運算符優先級進一步排序 減法大於加法 除法大於乘法
public static double caculate2(String formula) {
String[] arr = convert(formula);
Stack<Double> val = new Stack<>();
Stack<String> op = new Stack<>();

for (int i = 0; i < arr.length; i++) {
if (arr[i].equals("(")) {
val.push(caculate2(bracketGet(formula, i)));//遞歸計算括號內部的值,並將該值入棧
i = i + bracketGet(formula, i).length() + 1;
} else if (arr[i].equals("+") || arr[i].equals("-")
|| arr[i].equals("*") || arr[i].equals("/")) {
while (!op.isEmpty() && opcompare2(op.lastElement(), arr[i])) {
switch (op.pop()) {
case "+":
val.push(val.pop() + val.pop());
continue;
case "-":
double c = val.pop();
double d = val.pop();
val.push(d - c);
continue;
case "*":
val.push(val.pop() * val.pop());
continue;
case "/":
double a = val.pop();
double b = val.pop();
val.push(b / a);
continue;
default:
break;
}
}
op.push(arr[i]);
} else
val.push(Double.parseDouble(arr[i]));

}
while (!op.isEmpty()) {
switch (op.pop()) {
case "+":
val.push(val.pop() + val.pop());
break;
case "-":
double c = val.pop();
double d = val.pop();
val.push(d - c);
break;
case "*":
val.push(val.pop() * val.pop());
break;
case "/":
double a = val.pop();
double b = val.pop();
val.push(b / a);
break;
default:
break;
}
}

return val.pop();
}
/**
* 獲取括號內的字符串
* @param s
* @param k 從k位置開始獲取第一個帶完整的括號的子字符串
* @return
*/
public static String bracketGet(String s, int k) {
int m = 0;
int i;
String[] arr = convert(s);
for (i = k; i < arr.length; i++) {
if (arr[i].equals("(")) {
m++;
continue;
}
if (arr[i].equals(")")) {
m--;
if (m == 0)
break;
else
continue;
}

}
StringBuilder sb = new StringBuilder();
for (int j = k + 1; j < i; j++) {
sb.append(arr[j]);
}
return sb.toString();
}
/**
* 實現字符串表達式轉化為字符串數組,要求輸入的字符串中間沒有空格。
* @param s
* @return
*/
public static String[] convert(String s) {
ArrayList<String> arrayList = new ArrayList<>();
for (int i = 0; i < s.length(); i++) {
if (!opjudge(s.charAt(i))) {
int j = i;
while ((i < s.length()) && !opjudge(s.charAt(i)))
i++;
arrayList.add(s.substring(j, i));
i--;
} else{
arrayList.add(String.valueOf(s.charAt(i)));
}
}

return arrayList.toArray(new String[arrayList.size()]);

}
/**
* 判斷是否為運算符
* @param c
* @return
*/
public static boolean opjudge(char c) {
if (c == ‘+‘ || c == ‘-‘ || c == ‘*‘ || c == ‘/‘ || c == ‘(‘
|| c == ‘)‘)
return true;
else
return false;
}
/**
* 字符串的優先級,依次是除法 乘法 減法 加法 依次降低,遍歷到運算符時,優先級高才入棧
* @param s
* @return
*/
public static int opvalue2(String s) {
switch (s) {
case "+":
return 1;
case "-":
return 2;
case "*":
return 3;
case "/":
return 4;
default:
return -1;
}

}
/**
* 運算符優先級比較
* @param s1
* @param s2
* @return
*/
public static boolean opcompare2(String s1, String s2) {
if (opvalue2(s1) >= opvalue2(s2))
return true;
else {
return false;
}

}
}

技術分享

五、實驗總結

  逐步的,漸漸地更加清晰的懂得了體系結構的作用,能使得一個程序更加嚴謹,有條理。

130242014027-陳鋒-第2次實驗