请你用C语言中的栈写一段代码,用来求一个带小括号的四则运算的值,要求输入是字符串,打印出运算结果
时间: 2024-11-27 13:23:42 浏览: 13
简单四则运算,包括括号
4星 · 用户满意度95%
为了使用 C 语言的栈来求解带小括号的四则运算表达式,你需要实现一个解析器。这里是一个简单的例子,使用递归下降解析法来解决这个问题。我们将创建一个 `evaluate` 函数,它接受一个字符串输入,然后逐个处理数字、运算符和括号,最后返回计算后的值。下面是一个基本的实现:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct {
double value; // 存储当前计算的数值
char op; // 当前运算符
bool has_left_paren; // 标记左括号是否已经遇到
} Token;
// 初始化栈
Token stack[100];
// 检查下一个字符是否是运算符、数字、左括号或右括号
enum Type {NUMBER, OPERATOR, LEFT_PAREN, RIGHT_PAREN};
Type next_char(char *str) {
while (*str && !isdigit(*str) && !isspace(*str)) {
if (*str == '+' || *str == '-' || *str == '*' || *str == '/') {
return OPERATOR;
} else if (*str == '(') {
return LEFT_PAREN;
} else if (*str == ')') {
return RIGHT_PAREN;
}
str++;
}
if (isdigit(*str)) {
return NUMBER;
}
return END_OF_EXPRESSION;
}
// 将字符转换为整数
double to_number(const char *str) {
double num = 0;
while (isdigit(*str)) {
num *= 10;
num += *str - '0';
str++;
}
return num;
}
// 递归函数,处理运算
double evaluate_expression(char *expr) {
double result = 0;
bool done = false;
char *cur_str = expr;
// 主循环处理输入的每个部分
while (!done) {
// 1. 数字
if (next_char(cur_str) == NUMBER) {
Token token = {to_number(cur_str), '\0', false};
stack[++stack_top] = token;
cur_str += strlen(cur_str);
}
// 2. 左括号
else if (next_char(cur_str) == LEFT_PAREN) {
stack[++stack_top] = {'(', false};
cur_str++;
}
// 3. 右括号
else if (next_char(cur_str) == RIGHT_PAREN) {
while (stack_top > 0 && stack[stack_top].has_left_paren) {
double right_val = evaluate_expression(NULL); // 使用 NULL 来结束递归
double left_val = stack[--stack_top].value;
if (stack[stack_top].op == '(') {
stack[stack_top].value = right_val;
} else {
stack[stack_top].value = operate(left_val, stack[stack_top].op, right_val);
}
stack[stack_top].has_left_paren = false;
}
if (stack_top > 0 && !stack[stack_top].has_left_paren) {
done = true;
} else {
stack.pop(); // 移除左括号
cur_str++;
}
}
// 4. 运算符
else {
double right_val = evaluate_expression(NULL);
if (stack_top > 0) {
double left_val = stack[stack_top].value;
if (stack[stack_top].op != '(') {
stack[stack_top].value = operate(left_val, stack[stack_top].op, right_val);
}
} else {
stack.push({right_val, *cur_str, false}); // 如果栈为空,直接压入右边的值
}
stack_top--; // 减少栈顶,继续处理下个运算符
cur_str++;
if (next_char(cur_str) == END_OF_EXPRESSION) {
done = true;
}
}
}
// 最后一个元素是结果
result = stack[0].value;
return result;
}
// 操作符优先级
char operate(double left, char op, double right) {
switch (op) {
case '+': return left + right;
case '-': return left - right;
case '*': return left * right;
case '/': return left / right;
default: assert(false); // 避免未知运算符
}
}
int main() {
char expr[] = "3 + 5 * (2 - 1)";
printf("计算结果: %f\n", evaluate_expression(expr));
return 0;
}
```
这个程序首先定义了一个栈来存储运算过程中的数值和运算符。当遇到左括号时,它会进入一个递归的 `evaluate_expression` 函数,直到遇到对应的右括号。在运算符和数字之间,我们会先处理数字,然后处理运算符。请注意,此代码仅处理了最基础的四则运算,对于更复杂的情况可能需要进一步优化。
阅读全文