實驗一第一部分
在Linux中運行結果
通過cd和mkdir命令建立tree,帶包編譯並用
javac -d bin
的命令將編譯文件保存在bin目錄中
通過
java -cp
的命令運行帶包的程序
實驗第二部分
用idea調試程序
左鍵點擊行號旁邊的空白設置斷點。
用F7快捷鍵逐步運行代碼
用F9快捷建快速運行到下個斷點
右鍵點擊斷點可以設置循環條件
實驗第三部分
實驗題目:實現簡單的四則運算
實驗代碼:
import java.io.*;
import java.util.Stack;
public class siziyunsuan {
public static void main(String[] args) {
int i,f;
double result;
int zuokuohao1 = 0;
String ch2 = new String();
BufferedReader buf = new BufferedReader (new InputStreamReader(System.in));
try{
String str = buf.readLine();
f = chu0.chu0(str);
if(f == 0) {
char[] ch1 = str.toCharArray();
int len1 = ch1.length;
Stack<Character> operators = new Stack<>();
Stack output = new Stack<>();
zuokuohao1 = rpn(operators, output, str);
for (i = 0; i < len1 - 2 * zuokuohao1; i++) {
ch2 = output.pop() + ch2;
}
System.out.println(ch2);
result = jisuanhouxu.evaluate(ch2);
System.out.println(result);
}
else{
System.out.println("除數為0");
}
}catch(IOException e){
}
}
public static int rpn(Stack<Character> operators, Stack output, String str) {
char[] chars = str.toCharArray();
int pre = 0;
boolean digital;
int zuokuohao = 0;
int len = chars.length;
int bracket = 0;
for (int i = 0; i < len; ) {
pre = i;
digital = Boolean.FALSE;
while (i < len && !Operator.isOperator(chars[i])) {
i++;
digital = Boolean.TRUE;
}
if (digital) {
output.push(str.substring(pre, i));
} else {
char o = chars[i++];
if (o == '(') {
bracket++;
zuokuohao++;
}
if (bracket > 0) {
if (o == ')') {
while (!operators.empty()) {
char top = operators.pop();
if (top == '(') {
break;
}
output.push(top);
}
bracket--;
} else {
while (!operators.empty() && operators.peek() != '(' && Operator.cmp(o, operators.peek()) <= 0) {
output.push(operators.pop());
}
operators.push(o);
}
} else {
while (!operators.empty() && Operator.cmp(o, operators.peek()) <= 0) {
output.push(operators.pop());
}
operators.push(o);
}
}
}
while (!operators.empty()) {
output.push(operators.pop());
}
return zuokuohao;
}
}
enum Operator {
ADD('+', 1), SUBTRACT('-', 1),
MULTIPLY('*', 2), DIVIDE('/', 2),
LEFT_BRACKET('(', 3), RIGHT_BRACKET(')', 3);
char value;
int priority;
Operator(char value, int priority) {
this.value = value;
this.priority = priority;
}
public static int cmp(char c1, char c2) {
int p1 = 0;
int p2 = 0;
for (Operator o : Operator.values()) {
if (o.value == c1) {
p1 = o.priority;
}
if (o.value == c2) {
p2 = o.priority;
}
}
return p1 - p2;
}
public static boolean isOperator(char c) {
for (Operator o : Operator.values()) {
if (o.value == c) {
return true;
}
}
return false;
}
}
class jisuanhouxu {
public static double evaluate(String s) {
double c1 = 0;
double c2 = 0;
double d1 = 0;
double d2 = 0;
char[] ch = s.toCharArray();
Stack<Double> num = new Stack<>();
for (int i = 0; i < ch.length; i++) {
char c = ch[i];
if (c >= '0' && c <= '9') {
num.push(Double.parseDouble(Character.toString(c)));
} else {
switch (c) {
case '+':
num.push(num.pop() + num.pop());
break;
case '-':
c1 = num.pop();
c2 = num.pop();
num.push(c2 - c1);
break;
case '*':
num.push(num.pop() * num.pop());
break;
case '/':
d1 = num.pop();
d2 = num.pop();
num.push(d2 / d1);
break;
default:
break;
}
}
}
return num.pop();
}
}
class chu0{
public static int chu0(String s){
int i;
int flag = 0;
char[] ch = s.toCharArray();
for(i=0;i < ch.length;i++){
if(ch[i] == '/' && ch[i+1] == '0')
flag = 1;
}
return flag;
}
}
實驗運行結果
實驗中遇到的問題
1、首先是讀題問題。題目的要求應是鍵盤輸出式子,而不是隨機生成式子。隨機生成式子的代碼我寫了兩天,浪費了許多時間,但也不是沒有什么收獲。隨機生成式子的難點在於括號的插入,我一開始的想法是先生成不帶括號的式子,然后將括號插入其中。后面發現這樣實現起來需要考慮的地方太多。要考慮括號中間不能為空或者只有一個數,還有保證左右括號的數量相等,還有考慮多個左括號或右括號在一起的情況等等。於是我想能否在生成式子的過程中就插入括號呢?后來我還真找到一種方法,那就是通過對str = str1 + op + str2這個函數的遞歸生成式子,並在每次遞歸時通過概率判斷是否在str1或str2或str1 + op + str2的兩端通過拼接生成括號,這種方法生成括號不用考慮任何問題,生成帶括號的式子也不會有任何的數學語法錯誤(因不是實驗要求,沒有在代碼中展現)。
2、第二個難點就是編寫逆波蘭法。其中有兩個較難的地方。(1)是如何控制例如100這樣的多位數不被看成1,0,0三個元素。我通過雙計數的方式來解決,也就是i跟pre兩個變量計數,當循環遍歷到數字時,pre指向100中的1,i通過i++的方式循環到100中末位的0,使用String類里的方法substring(pre, i)將1,0,0看作100輸出。第二個難點就在於棧里的數據已經按后序排好(假設是32),可由於棧是先進后出,讀出來的結果會是23,所以我想到了用字符串向前拼接的方式ch2 = output.pop() + ch2;就能輸出32*。
3、第三個問題是在多次運行程序時有時候值會出現 infinity,后經過調試發現是沒有考慮到除0的特殊情況,於是我通過編寫chu0類,並在chu0中編寫靜態方法能夠判斷是否有除0的情況並通過返回flag的值控制程序。
4、最后一個就是時間的安排問題。我提前三天開始寫實驗,本以為足夠完成實驗,可沒有想到出現讀題錯誤的特殊情況,讓前兩天的工作覆水東流,最后只剩一天的時間編寫實驗程序導致不能按時完成。所以以后對於較大任務量的作業,一定要盡早安排時間完成,防止突發情況的發生。