写在前面
首先祝各位除夕快乐!
在寒假已经过半的现在,本想写个游戏程序的我因为各种各样的琐事迟迟未能动工。于是想至少在年前写点什么。恰逢前段时间看了个介绍递归的网课,便心血来潮,想要写一个以递归实现四则运算表达式自动求值的程序。于是开始动工。
本程序启发自Mooc 郭炜老师的北京大学《程序设计与算法(二)算法基础》。
介于本人是编程初学者,因此本文很多地方可能会有概念性或者认知上的错误,在此也欢迎各位读者批评斧正。
本文由FlexLian编写,如有搬运请声明出处。版权所有,仿冒必究。
程序说明
本程序以递归实现四则运算表达式的自动匹配求值。具备除数为零时的报错能力,有一定的实用性。总体采用面向对象的思想,将各大功能封装在两个类中。
对于一个四则运算表达式,我们可以将其视作 表达式(总体) -> 项 (每两个项之间由加或减连接)-> 因子 (每两个因子之间由乘或除连接) -> 子表达式 (由括号括起)-> …… 由此类推向下递推,因而可以以递归的形式获取总表达式的值。
以下是源代码
程序代码
import java.util.*;
public class Main {
private static Cin cin;
private static Scanner input = new Scanner(System.in);
private static class Cin { // 用于递归中获取表达式内容
private String myExpression; // 存储表达式
private int index; // 模拟字符指针,用于获取当前指向表达式
private int size; // 存储表达式长度
public Cin() { // 当输入为空进行处理
this("");
}
public Cin(String s) { // 类的初始化
this.myExpression = s;
this.index = 0;
this.size = s.length();
}
public char peek() { // 获取当前模拟字符指针指向的字符
if(index >= size) return '?'; // 当模拟字符指针指向表达式外,则返回非表达式常用字符防止异常
return myExpression.charAt(index);
}
public void get() { // 模拟字符指针后移
index += 1;
}
}
private static class Solution {
private boolean isDigit(char n) { // 判断参数字符是否为数字字符
return (n >= '0' && n <= '9');
}
public int expressionValue() throws Exception { // 获取 表达式 或 子表达式 (由加法和减法组成) 的值
int result = termValue();
while(true) {
int c = cin.peek();
if(c == '+' || c == '-') cin.get(); // 当获取到的字符为'+'和'-'时才继续向下执行后续操作
else break;
if(c == '+') {
result += termValue();
} else if(c == '-') {
result -= termValue();
}
}
return result;
}
public int factorValue() throws Exception { // 获取 因子 (数)的值
int result = 0;
char c = cin.peek();
if(c == '(') { // 若 因子 中存在子表达式, 则 求取子表达式的值
cin.get();
result += expressionValue();
cin.get();
} else {
while (isDigit(c)) { // 若当前字符为数字字符,则将其转化为整型数字并添加到返回结果中
cin.get();
result = 10 * result + (c - '0');
c = cin.peek();
}
}
return result;
}
public int termValue() throws Exception { // 获取 项 (由乘法及除法组成)的值
int result = factorValue();
while(true) {
char c = cin.peek();
if(c == '*' || c == '/') cin.get(); // 当获取到的字符为'*'和'/'时才继续向下执行后续操作
else break;
if(c == '*') {
result *= factorValue();
} else if(c == '/') {
int tmp = factorValue();
if(tmp == 0) throw new Exception("除数为0!"); // 当除数为零,报错
result /= tmp;
}
}
return result;
}
}
public static void main(String []args) {
String expression = input.next();
cin = new Cin(expression);
Solution solution = new Solution();
try {
System.out.println(solution.expressionValue());
} catch (Exception e) {
System.out.println(e.getMessage());
}
input.close();
}
}
运行效果