用c语言做一下代码作业,写下注释及详细代码思路。基本要求:以字符序列的形式从键盘输入语法正确的,不含变量的整型表达式。利用教科书表3.1给出的算符优先关系,实现对算术四则混合运算表达式的求值,并仿照教科书的例3.1演示在求值中运算符栈、运算数栈、输入字符和主要操作的变化过程。 测试数据:3*(7-2) 1+2+3+4 88-1*5 1024/4*8 1024/(4*8) (20+2)*(6/2) 3-3-3 8/(9-9) 2*(6+2*(3+6*(6+6))) (((6+6)*6+3)*2+6)*2 实现提示:(1)设置运算符栈和运算数栈辅助分析算符优先关系。 (2)在读入表达式的字符序列的同时,完成运算符和运算数(整数)的识别处理,以及相应的运算。 (3)在识别出运算数的同时,要将其字符序列形式转换成整数形式。 (4)在程序的适当位置输出运算符栈、运算数栈、输入字符和主要操作的内容。
时间: 2024-03-09 16:49:43 浏览: 21
思路:
1. 定义两个栈,一个运算符栈,一个运算数栈。
2. 从键盘输入表达式,遍历表达式的每一个字符。
3. 如果是数字字符,就将其转化为整数并压入运算数栈。
4. 如果是运算符,就将其与运算符栈栈顶的运算符比较优先级。
5. 如果比栈顶运算符优先级高,就将此运算符压入运算符栈。
6. 如果比栈顶运算符优先级低或相等,就从运算符栈中弹出栈顶运算符,从运算数栈中弹出两个元素进行运算,并将结果压入运算数栈中。然后再次比较此运算符与栈顶运算符的优先级。
7. 当遍历完整个表达式后,将运算符栈中的运算符弹出并进行相应运算,直到运算符栈为空。
8. 输出最终结果。
代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // 包含 isdigit() 函数的头文件
#define STACK_SIZE 100
// 定义栈结构体
typedef struct {
int data[STACK_SIZE];
int top;
} Stack;
// 初始化栈
void init_stack(Stack *s) {
s->top = -1;
}
// 判断栈是否为空
int is_empty(Stack *s) {
return (s->top == -1);
}
// 判断栈是否已满
int is_full(Stack *s) {
return (s->top == STACK_SIZE - 1);
}
// 压栈操作
void push(Stack *s, int x) {
if (is_full(s)) {
printf("Error: Stack is full!\n");
exit(1);
}
s->data[++(s->top)] = x;
}
// 出栈操作
int pop(Stack *s) {
if (is_empty(s)) {
printf("Error: Stack is empty!\n");
exit(1);
}
return s->data[(s->top)--];
}
// 获取栈顶元素
int get_top(Stack *s) {
if (is_empty(s)) {
printf("Error: Stack is empty!\n");
exit(1);
}
return s->data[s->top];
}
// 获取运算符优先级
int get_priority(char ch) {
switch (ch) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '(':
return 0;
default:
printf("Error: Invalid operator!\n");
exit(1);
}
}
// 将字符序列转换成整数
int str_to_int(char *str) {
int result = 0;
while (*str) {
result = result * 10 + (*str - '0');
str++;
}
return result;
}
// 处理表达式
int calculate(char *expr) {
int num = 0;
int flag = 0; // 标识是否遇到数字
Stack num_stack, op_stack; // 运算数栈和运算符栈
init_stack(&num_stack);
init_stack(&op_stack);
while (*expr) {
if (isdigit(*expr)) { // 如果遇到数字字符
num = num * 10 + (*expr - '0'); // 将其转化为整数
flag = 1;
} else { // 如果遇到运算符
if (flag) { // 如果前面有数字字符,就将其压入运算数栈
push(&num_stack, num);
num = 0;
flag = 0;
}
if (*expr == '(') { // 如果是左括号,直接压入运算符栈
push(&op_stack, *expr);
} else if (*expr == ')') { // 如果是右括号,弹出运算符栈中的运算符进行运算
while (get_top(&op_stack) != '(') {
int num2 = pop(&num_stack);
int num1 = pop(&num_stack);
char op = pop(&op_stack);
switch (op) {
case '+':
push(&num_stack, num1 + num2);
break;
case '-':
push(&num_stack, num1 - num2);
break;
case '*':
push(&num_stack, num1 * num2);
break;
case '/':
push(&num_stack, num1 / num2);
break;
}
}
pop(&op_stack); // 弹出左括号
} else { // 如果是其他运算符
while (!is_empty(&op_stack) && get_priority(*expr) <= get_priority(get_top(&op_stack))) {
// 如果比栈顶元素优先级低或相等,就弹出栈顶元素进行运算
int num2 = pop(&num_stack);
int num1 = pop(&num_stack);
char op = pop(&op_stack);
switch (op) {
case '+':
push(&num_stack, num1 + num2);
break;
case '-':
push(&num_stack, num1 - num2);
break;
case '*':
push(&num_stack, num1 * num2);
break;
case '/':
push(&num_stack, num1 / num2);
break;
}
}
push(&op_stack, *expr); // 将此运算符压入运算符栈
}
}
expr++; // 继续处理下一个字符
}
if (flag) { // 处理最后一个数字字符
push(&num_stack, num);
}
while (!is_empty(&op_stack)) { // 处理剩余的运算符
int num2 = pop(&num_stack);
int num1 = pop(&num_stack);
char op = pop(&op_stack);
switch (op) {
case '+':
push(&num_stack, num1 + num2);
break;
case '-':
push(&num_stack, num1 - num2);
break;
case '*':
push(&num_stack, num1 * num2);
break;
case '/':
push(&num_stack, num1 / num2);
break;
}
}
return pop(&num_stack); // 返回最终结果
}
int main() {
char expr[100]; // 存储输入的表达式
int result;
printf("Please enter an expression: ");
gets(expr);
result = calculate(expr);
printf("Result: %d\n", result);
return 0;
}
```
由于输入的表达式中不含变量,因此可以直接使用 `gets()` 函数从键盘输入整个表达式。然后,我们遍历表达式的每一个字符,将数字字符转换为整数,并将其压入运算数栈中;如果遇到运算符,就将其与运算符栈栈顶的运算符比较优先级,然后进行相应的处理。最后,将运算符栈中的运算符依次弹出并进行相应的运算,直到运算符栈为空,最终结果就是运算数栈中唯一的元素。在程序的适当位置输出运算符栈、运算数栈、输入字符和主要操作的内容,可以方便我们理解程序的运行过程。