题目:要求输入一个表达式字符串,利用递归,求解表达式的值
如:(5 * 10) + ((3 * 6) - 7)
解题思路
找到表达式中优先级(数值)最低的运算符,以该运算符分割表达式,然后递归求解。
设定:+、-
优先级数值为 1,*、/
优先级数值为 2,如果遇到(
,那么之后遇到的运算符优先级数值都+100,当遇到)
时,优先级数值-100
代码
变量声明:
char[] c
:存储表达式中的每一个字符的字符数组op
:用于定位优先级最小的运算符的位置(字符数组下标),初始值-1pri
:用于记录当前处理的表达式中最低优先级的优先级数值,初始值10000-1cur_pri
:用于记录字符数组中每个字符的优先级 每次循环都要初始化 初始值为10000temp
:用于记录由括号带来的临时优先级s
:表达式字符串head
:头下标(用于限定需要处理的表达式的范围)tail
:尾下标(用于限定需要处理的表达式的范围)
public int clic(String s, int head, int tail){
char[] c = s.toCharArray();//将表达式字符串转换为字符数组
int op = -1, pri = 10000 - 1, cur_pri, temp = 0;//定义变量
//遍历字符数组中的运算符
for(int i = head; i <= tail; i++){
cur_pri = 10000;//每次循环都初始化当前字符的优先级,避免非运算符的字符参与比较
switch (c[i]){
case '+':
case '-': cur_pri = 1 + temp;break;
case '*':
case '/': cur_pri = 2 + temp;break;
case '(': temp += 100;break;
case ')': temp -= 100;break;
}
//如果当前运算符的优先级数值小于目前表达式中最低的优先级数值的话
if(cur_pri < pri){
pri = cur_pri;//更新目前表达式中的最低优先级数值
op = i;//指针指向该运算符
}
}
//程序运行至此,op指向的运算符就是该表达式中的最低优先级运算符
//如果op是是-1的话,证明该串中没有运算符,那么将其转换为纯数子
if(op == -1){
int num = 0;
for(int i = head; i <= tail; i ++){
if(c[i] > '9' || c[i] < '0'){ //过滤括号和空格等非数字字符
continue;
}
num = num * 10 + (c[i] - '0');//数字字符-字符0可得整型数字
}
return num;
}
//以该运算符分割字符串
int a = clic(s, head, op-1);
int b = clic(s, op+1, tail);
//运算
switch (c[op]){
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/': return a / b;
}
return 0;
}
总结
- 数字字符转对应数字如
'7'->7
时,错误:(int)'7'
,正确'7'-'0'
因为(int)
强转获得的是'7'
的ASCII码 - 字符串转字符数组:
char[] c = str.toCharArry();
- 递归实际上就是使用的系统栈进行变量存储,可以将递归与栈结合理解