c语言,用户从键盘输入一个算术表达式,数字都是十进制整型(必须支持负数),运算符支持+-*/()。不用栈
时间: 2023-11-13 19:05:58 浏览: 83
可以使用递归解析表达式,每次递归处理一个运算符和它两边的操作数。
具体实现过程如下:
1. 定义一个函数`calc(char *expr, int start, int end, int *result)`,用于计算从`start`到`end`位置的表达式并将结果存储在`result`中。
2. 在`calc`函数内部,从左往右扫描表达式,找到优先级最低的运算符(括号除外),将表达式分成左右两部分,分别递归调用`calc`函数计算左右两部分的值,最后根据运算符计算整个表达式的值。
3. 如果扫描到的字符是数字或负号,就将其转换为整型数值,如果是左括号,则需要找到与之匹配的右括号,并将括号内的表达式作为参数递归调用`calc`函数。
4. 最后返回计算结果。
完整代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int calc(char *expr, int start, int end, int *result);
int main()
{
char expr[100];
int result = 0;
printf("请输入一个算术表达式:\n");
scanf("%s", expr);
if (calc(expr, 0, strlen(expr) - 1, &result)) {
printf("计算结果:%d\n", result);
} else {
printf("表达式不合法\n");
}
return 0;
}
int calc(char *expr, int start, int end, int *result)
{
int i, j, k, op, left, right, res;
char buf[20];
/* 去掉左右两边的空格 */
while (start <= end && isspace(expr[start])) start++;
while (start <= end && isspace(expr[end])) end--;
/* 处理负数 */
if (expr[start] == '-') {
if (isdigit(expr[start + 1])) {
i = start + 1;
while (i <= end && isdigit(expr[i])) i++;
strncpy(buf, expr + start, i - start);
buf[i - start] = '\0';
*result = atoi(buf);
return 1;
} else {
return 0;
}
}
/* 查找最低优先级的运算符 */
op = -1;
for (i = start; i <= end; i++) {
if (expr[i] == '(') {
k = 1;
while (k > 0) {
i++;
if (i > end) return 0;
if (expr[i] == '(') k++;
else if (expr[i] == ')') k--;
}
} else if (expr[i] == '+' || expr[i] == '-') {
if (op < 0) op = i;
} else if (expr[i] == '*' || expr[i] == '/') {
if (op < 0 || expr[op] == '+' || expr[op] == '-') op = i;
}
}
if (op >= 0) {
/* 递归计算左右两部分的值 */
if (!calc(expr, start, op - 1, &left)) return 0;
if (!calc(expr, op + 1, end, &right)) return 0;
/* 根据运算符计算结果 */
switch (expr[op]) {
case '+': res = left + right; break;
case '-': res = left - right; break;
case '*': res = left * right; break;
case '/': res = right == 0 ? 0 : left / right; break;
}
*result = res;
return 1;
} else if (expr[start] == '(' && expr[end] == ')') {
/* 去掉括号,并递归处理括号内的表达式 */
return calc(expr, start + 1, end - 1, result);
} else {
/* 处理单个数字 */
i = start;
while (i <= end && isdigit(expr[i])) i++;
strncpy(buf, expr + start, i - start);
buf[i - start] = '\0';
*result = atoi(buf);
return i > start;
}
}
```
需要注意的是,这个算法并没有使用栈,因此在处理嵌套括号时需要使用递归来实现。此外,在处理负数时,需要特判负号前面是否有数字,以区分减号和负号。
阅读全文