2018-2019-2 20175328 实验一《Java开发环境的熟悉》实验报告
一、实验内容及步骤
(一)建立目录,并在目录下运行Javac和java
1 建立“自己学号exp1”的目录
2 在“自己学号exp1”目录下建立src,bin等目录
3 javac,java的执行在“自己学号exp1”目录
(二)在IDEA中调试设置条件断点
(三)练习——实现简单四则运算
JiSuan.java
import java.util.*;
public class JiSuan { //将中缀表达式字符串转换为后缀表达式
public JiSuan() { // 默认构造
}
public static double jiSuan(String string) { // 将中缀表达式字符串计算得到结果
return suffixToArithmetic(infixToSuffix(string));
}
public static String infixToSuffix(String exp) { // 将中缀表达式转换为后缀表达式
Stack<Character> s = new Stack<Character>(); // 创建操作符堆栈
String suffix = ""; // 要输出的后缀表达式字符串
int length = exp.length(); // 输入的中缀表达式的长度
for (int i = 0; i < length; i++) {
char temp;// 临时字符变量
char ch = exp.charAt(i); // 获取该中缀表达式的每一个字符并进行判断
switch (ch) {
case ' ': // 忽略空格
break;
case '(': // 如果是左括号直接压入堆栈
s.push(ch);
break;
case '+': // 碰到'+' '-',将栈中的所有运算符全部弹出去,直至碰到左括号为止,输出到队列中去
case '-':
while (s.size() != 0) {
temp = s.pop();
if (temp == '(') {
s.push('('); // 重新将左括号放回堆栈,终止循环
break;
}
suffix += temp;
}
s.push(ch); // 没有进入循环说明是当前为第一次进入或者其他前面运算都有括号等情况导致栈已经为空,此时需要将符号进栈
break;
case '*': // 如果是乘号或者除号,则弹出所有序列,直到碰到加好、减号、左括号为止,最后将该操作符压入堆栈
case '/':
while (s.size() != 0) {
temp = s.pop();
if (temp == '+' || temp == '-' || temp == '(') { // 只有比当前优先级高的或者相等的才会弹出到输出队列,遇到加减左括号,直接停止当前循环
s.push(temp);
break;
} else {
suffix += temp;
}
}
s.push(ch);
break;
case ')': // 如果碰到的是右括号,则距离栈顶的第一个左括号上面的所有运算符弹出栈并抛弃左括号
while (!s.isEmpty()) {
temp = s.pop();
if (temp == '(') {
break;
} else {
suffix += temp;
}
}
break;
default: // 默认情况,如果读取到的是数字,则直接送至输出序列
suffix += ch;
break;
}
}
while (s.size() != 0) { // 如果堆栈不为空,则把剩余运算符一次弹出,送至输出序列
suffix += s.pop();
}
return suffix;
}
public static double suffixToArithmetic(String exp) {
Pattern pattern = Pattern.compile("\d+||(\d+\.\d+)"); // 使用正则表达式匹配数字
String[] strings = exp.split(""); // 将后缀表达式分割成字符串数组,此处直接使用空白对字符串进行分割
Stack<Double> stack = new Stack<Double>();
for (int i = 0; i < strings.length; i++) { // 进行判断彻底消除空格,在该数组的第一位为一个隐形的空格
if (strings[i].equals("")) { // 由于使用的是""截取导致在数组第一位上面的值为空白
continue;
}
if (pattern.matcher(strings[i]).matches()) { // 如果遇到了数字则直接进栈
stack.push(Double.parseDouble(strings[i]));
}
else { // 如果是运算符,则弹出栈顶的两个数进行计算
double y = stack.pop();
double x = stack.pop();
stack.push(calculate(x, y, strings[i])); // 将运算结果重新压栈
}
}
return stack.pop(); // 弹出栈顶元素就是最终结果
}
private static Double calculate(double x, double y, String string) {
if (string.trim().equals("+")) {
return x + y;
}
if (string.trim().equals("-")) {
return x - y;
}
if (string.trim().equals("*")) {
return x * y;
}
if (string.trim().equals("/")) {
return x / y;
}
return (double) 0;
}
}
Main.java
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args){
Stack<Character> s = new Stack<Character>();
Scanner scan = new Scanner(System.in);
String ch=scan.next();
System.out.println(JiSuan.infixToSuffix(ch));
System.out.println(JiSuan.jiSuan(ch));
}
}
运行截图:
二、遇到的问题及解决办法
1、问题:编译的时候会显示找不到符号
解决方法:通过百度搜素,发现是编译时程序中的一些类找不到,为了方便且正确,我们可以在程序一开头加上一些常用的包或类([https://www.cnblogs.com/julinhuitianxia/p/6850493.html][1])
如:
import java.io.;
import java.util.;
2、问题:不知道字符串应该怎样输入,以为是用
String ch=scan.nextString();
解决方法:从百度上搜到用
Scanner scan = new Scanner(System.in);
String ch=scan.next();
三、实验总结
1、在写代码的时候,如果能够记住很多快捷键,往往能很大的方便自己。
2、平时老师的课上测试和实验的感觉是不一样的,测试比较注重的是某个点,而实验的话就需要我们去更加全面的进行考虑。我们要在编程序之前就把框架给搭好,然后照着思路往下写,如果边想边写或边写边想,很多时候会浪费大量的时间。