用c语言解决1. 表达式求值问题,应用“栈”编写一个计算器,要求: a) 支持整数(长整型范围内)四则混合运算; b) 输入应是中缀表达式,对不合法的输入应有提示; c) 能够输出正确计算结果; d) 示例 如 输入 5*(10-3) / 7 ,输出结果 5

时间: 2024-01-22 21:20:38 浏览: 22
以下是使用C语言解决表达式求值问题的代码,其中使用了栈数据结构: ``` #include <stdio.h> #include <stdlib.h> #include <ctype.h> #include <string.h> #define MAX_EXPR_LEN 1000 #define MAX_STACK_SIZE 1000 typedef struct stack { int top; long long data[MAX_STACK_SIZE]; } Stack; void push(Stack *s, long long x) { if (s->top == MAX_STACK_SIZE - 1) { printf("Stack overflow!\n"); exit(EXIT_FAILURE); } s->data[++(s->top)] = x; } long long pop(Stack *s) { if (s->top == -1) { printf("Stack underflow!\n"); exit(EXIT_FAILURE); } return s->data[(s->top)--]; } long long peek(Stack *s) { if (s->top == -1) { printf("Stack underflow!\n"); exit(EXIT_FAILURE); } return s->data[s->top]; } int is_operator(char c) { return (c == '+' || c == '-' || c == '*' || c == '/'); } int precedence(char c) { if (c == '*' || c == '/') { return 2; } else if (c == '+' || c == '-') { return 1; } else { return 0; } } int is_valid_input(char *expr) { int len = strlen(expr); int bracket_count = 0; for (int i = 0; i < len; i++) { char c = expr[i]; if (isdigit(c)) { continue; } else if (is_operator(c)) { if (i == 0 || i == len - 1) { return 0; } else if (is_operator(expr[i-1]) || is_operator(expr[i+1])) { return 0; } } else if (c == '(') { bracket_count++; } else if (c == ')') { bracket_count--; if (bracket_count < 0) { return 0; } } else { return 0; } } return (bracket_count == 0); } long long evaluate(char *expr) { if (!is_valid_input(expr)) { printf("Invalid input!\n"); exit(EXIT_FAILURE); } Stack operand_stack, operator_stack; operand_stack.top = -1; operator_stack.top = -1; int len = strlen(expr); int i = 0; while (i < len) { char c = expr[i]; if (isdigit(c)) { long long num = 0; while (i < len && isdigit(expr[i])) { num = 10 * num + (expr[i] - '0'); i++; } push(&operand_stack, num); } else if (is_operator(c)) { while (operator_stack.top >= 0 && precedence(peek(&operator_stack)) >= precedence(c)) { long long op2 = pop(&operand_stack); long long op1 = pop(&operand_stack); char op = pop(&operator_stack); if (op == '+') { push(&operand_stack, op1 + op2); } else if (op == '-') { push(&operand_stack, op1 - op2); } else if (op == '*') { push(&operand_stack, op1 * op2); } else if (op == '/') { push(&operand_stack, op1 / op2); } } push(&operator_stack, c); i++; } else if (c == '(') { push(&operator_stack, c); i++; } else if (c == ')') { while (peek(&operator_stack) != '(') { long long op2 = pop(&operand_stack); long long op1 = pop(&operand_stack); char op = pop(&operator_stack); if (op == '+') { push(&operand_stack, op1 + op2); } else if (op == '-') { push(&operand_stack, op1 - op2); } else if (op == '*') { push(&operand_stack, op1 * op2); } else if (op == '/') { push(&operand_stack, op1 / op2); } } pop(&operator_stack); i++; } else { printf("Invalid input!\n"); exit(EXIT_FAILURE); } } while (operator_stack.top >= 0) { long long op2 = pop(&operand_stack); long long op1 = pop(&operand_stack); char op = pop(&operator_stack); if (op == '+') { push(&operand_stack, op1 + op2); } else if (op == '-') { push(&operand_stack, op1 - op2); } else if (op == '*') { push(&operand_stack, op1 * op2); } else if (op == '/') { push(&operand_stack, op1 / op2); } } return pop(&operand_stack); } int main() { char expr[MAX_EXPR_LEN]; printf("Enter an expression: "); fgets(expr, MAX_EXPR_LEN, stdin); expr[strlen(expr)-1] = '\0'; // remove the newline character from the input long long result = evaluate(expr); printf("Result: %lld\n", result); return 0; } ``` 这个代码使用两个栈:一个用于存储操作数(operand),一个用于存储运算符(operator)。 首先,程序检查输入是否合法。表达式中只能包含数字、加减乘除运算符和括号,而且括号必须匹配。如果输入不合法,程序会输出错误信息并退出。 然后,程序遍历中缀表达式,根据以下规则进行计算: - 如果遇到数字,将其作为操作数入栈 operand_stack 中; - 如果遇到运算符,将其与 operator_stack 栈顶的运算符进行比较。如果栈顶的运算符优先级大于等于当前运算符,就从 operator_stack 中弹出一个运算符,从 operand_stack 中弹出两个操作数,进行计算并将结果入栈 operand_stack 中。重复这个过程直到栈顶的运算符优先级小于当前运算符,然后将当前运算符入栈 operator_stack 中; - 如果遇到左括号,将其直接入栈 operator_stack 中; - 如果遇到右括号,将 operator_stack 中的运算符依次弹出,并从 operand_stack 中弹出两个操作数进行计算,直到遇到左括号为止。左括号不入栈 operand_stack 中; - 如果遇到其他字符,说明输入不合法,程序会输出错误信息并退出。 最后,当中缀表达式遍历结束后,需要将 operator_stack 中的所有运算符依次弹出,从 operand_stack 中弹出两个操作数进行计算,直到 operator_stack 为空。最终 operand_stack 中只剩下一个操作数,就是表达式的计算结果。

相关推荐

最新推荐

recommend-type

表达式求值顺序栈实现包括小数点运算(C语言版).docx

使用两个栈,stack0用于存储操作数,stack1用于存储操作符 从左往右扫描,遇到操作数入栈stack0 遇到操作符时,如果优先级低于或等于栈顶操作符优先级,则从stack0弹出两个元素进行计算,并压入stack0,继续与栈顶...
recommend-type

c语言 实现二叉树操作 用栈实现算术表达式求值

(1)题目一的内容和要求: 1、编写已知二叉树的先序、中序序列,恢复此二叉树的程序 2、编写求二叉树深度的程序 ... 2、将一个表达式的中缀形式转化为相应的后缀形式 3、依据后缀表达式计算表达式的值
recommend-type

C语言之整数划分问题(递归法)实例代码

主要介绍了C语言之整数划分问题(递归法)实例代码的相关资料,需要的朋友可以参考下
recommend-type

天然气汽车供气系统减压装置毕业设计(cad+设计方案).zip

天然气汽车供气系统减压装置毕业设计(cad+设计方案)
recommend-type

PHP+SQL考勤系统安全性实现(源代码+论文+答辩PPT+指导书)

PHP+SQL考勤系统安全性实现(源代码+论文+答辩PPT+指导书)
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

解答下列问题:S—>S;T|T;T—>a 构造任意项目集规范族,构造LR(0)分析表,并分析a;a

对于这个文法,我们可以构造以下项目集规范族: I0: S -> .S S -> .T T -> .a I1: S -> S. [$ T -> T. [$ I2: S -> T. I3: S -> S.;S S -> S.;T T -> T.;a 其中,点(.)表示已经被扫描过的符号,;$表示输入串的结束符号。 根据项目集规范族,我们可以构造出LR(0)分析表: 状态 | a | $ ---- | - | - I0 | s3| I1 | |acc I2 | | 其中s3表示移进到状态3,acc表示接受。在分析字符串a;a时,我们可以按照以下步骤进行
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。