以下是一个使用C语言编写的代码示例,实现了对任意多位中缀表达式的求值。在这个代码中,运算符优先级已经被考虑进去。
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100
// 定义栈结构
typedef struct {
double data[MAX_SIZE];
int top;
} Stack;
// 初始化栈
void initStack(Stack *s) {
s->top = -1;
}
// 判断栈是否为空
int isEmpty(Stack *s) {
return s->top == -1;
}
// 入栈操作
void push(Stack *s, double value) {
if (s->top >= MAX_SIZE - 1) {
printf("栈已满,无法入栈!\n");
exit(1);
}
s->data[++(s->top)] = value;
}
// 出栈操作
double pop(Stack *s) {
if (isEmpty(s)) {
printf("栈已空,无法出栈!\n");
exit(1);
}
return s->data[(s->top)--];
}
// 获取栈顶元素
double getTop(Stack *s) {
if (isEmpty(s)) {
printf("栈已空,无法获取栈顶元素!\n");
exit(1);
}
return s->data[s->top];
}
// 获取运算符优先级(数字越大表示优先级越高)
int getPriority(char operator) {
switch (operator) {
case '+':
case '-':
return 0;
case '*':
case '/':
return 1;
default:
return -1; // 非法运算符
}
}
// 判断是否为数字字符
int isDigit(char ch) {
return (ch >= '0' && ch <= '9') || ch == '.';
}
// 计算中缀表达式的值
double calculate(char *expression) {
Stack numStack; // 数字栈
Stack opStack; // 运算符栈
initStack(&numStack);
initStack(&opStack);
while (*expression != '\0') {
if (isDigit(*expression)) { // 当前字符是数字,则读取完整数字并入栈
char *endptr;
double number = strtod(expression, &endptr);
expression = endptr;
push(&numStack, number);
} else if (*expression == '(') { // 左括号直接入运算符栈
push(&opStack, *expression);
expression++;
} else if (*expression == ')') { // 右括号,进行计算直到遇到左括号
while (getTop(&opStack) != '(') {
char op = pop(&opStack);
double num2 = pop(&numStack);
double num1 = pop(&numStack);
switch (op) {
case '+':
push(&numStack, num1 + num2);
break;
case '-':
push(&numStack, num1 - num2);
break;
case '*':
push(&numStack, num1 * num2);
break;
case '/':
if (num2 == 0.0) {
printf("除数不能为0!\n");
exit(1);
}
push(&numStack, num1 / num2);
break;
}
}
pop(&opStack); // 弹出左括号
expression++;
} else if (*expression == '+' || *expression == '-' || *expression == '*' || *expression == '/') {
while (!isEmpty(&opStack) && getPriority(getTop(&opStack)) >= getPriority(*expression)) {
char op = pop(&opStack);
double num2 = pop(&numStack);
double num1 = pop(&numStack);
switch (op) {
case '+':
push(&numStack, num1 + num2);
break;
case '-':
push(&numStack, num1 - num2);
break;
case '*':
push(&numStack, num1 * num2);
break;
case '/':
if (num2 == 0.0) {
printf("除数不能为0!\n");
exit(1);
}
push(&numStack, num1 / num2);
break;
}
}
push(&opStack, *expression); // 当前运算符入栈
expression++;
} else { // 非法字符,直接退出
printf("输入包含非法字符!\n");
exit(1);
}
}
while (!isEmpty(&opStack)) { // 最后将剩余的运算符进行计算
char op = pop(&opStack);
double num2 = pop(&numStack);
double num1 = pop(&numStack);
switch (op) {
case '+':
push(&numStack, num1 + num2);
break;
case '-':
push(&numStack, num1 - num2);
break;
case '*':
push(&numStack, num1 * num2);
break;
case '/':
if (num2 == 0.0) {
printf("除数不能为0!\n");
exit(1);
}
push(&numStack, num1 / num2);
break;
}
}
return pop(&numStack); // 返回最终结果
}
int main() {
char expression[MAX_SIZE];
printf("请输入中缀表达式:");
scanf("%s", expression);
double result = calculate(expression);
printf("计算结果:%lf\n", result);
return 0;
}
请注意,此代码仅处理基本的四则运算和括号,并没有处理负数、小数和除数为零的错误情况。如果需要增加这些功能,可以在相应的部分进行修改和完善。
内容由零声教学AI助手提供,问题来源于学员提问