首先,将中缀表达式转换成后缀表达式,用压栈的方法:
1.遇到操作数,直接输出;
2.栈为空时,遇到运算符,入栈;
3.遇到左括号,将其入栈;
4.遇到右括号,执行出栈操作,直到弹出栈的元素是左括号,左括号不输出;
5.遇到其他运算符'+''-''*''/'时,弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈;
6.遇到结束符后将栈中的元素依次出栈,输出。
然后计算后缀表达式的值:
1.遇到的是数据,直接压栈;
2.遇到的是操作符,从栈中弹出两个元素,结合操作符计算出结果,再将结果压入栈中;
3.将最后的结果出栈。
//filename:cal_expression.h
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <ctype.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define DATA_NODE 1
#define OP_NODE 0
#define MAX_EXPRESSION_LENGTH 50
struct Node
{
int flag; //结点标识 1 数据节点; 0 符号节点
int data; //数据
char op; //操作符
struct Node *next;
};
struct LStack
{
struct Node *top;
struct Node *base;
};
//栈初始化
void init_stack(struct LStack *linkStack);
//判断栈是否为空
int is_stack_empty(struct LStack *linkStack);
//进栈,数num进栈
int push_stack(struct LStack *linkStack, int num, int flag);
//出栈,出战元素保存在num中
int pop_stack(struct LStack *linkStack);
//获取栈顶操作符元素,放入c中
int get_op_elem(struct LStack linkStack, char *c);
//获取栈顶数据元素,放入num中
int get_data_elem(struct LStack linkStack, int *num);
//销毁栈
int destory_stack(struct LStack *linkStack);
//获取栈的长度,将长度返回
int get_stack_length(struct LStack linkStack);
//打印栈内的数据元素
void print_stack(struct LStack linkStack);
//获取中缀表达式
int get_infix(char *infix);
//将中缀表达式转换成后缀表达式
int infix_to_postfix(char *infix, char *postfix);
//将整形数转化成操作符
char int_to_operator(int num);
//计算中缀表达式的值
int calculate_postfix(char *postfix, int *result);
//filename:link_stack.c
#include "cal_expression.h"
//栈初始化
void init_stack(struct LStack *linkStack)
{
linkStack->base = NULL;
linkStack->top = NULL;
}
//判断栈是否为空
int is_stack_empty(struct LStack *linkStack)
{
return ((linkStack->base == NULL) ? TRUE : FALSE);
}
//进栈,数num进栈
int push_stack(struct LStack *linkStack, int num, int flag)
{
struct Node *tmp_node = (struct Node *)malloc(sizeof(struct Node));
if(tmp_node == NULL)
{
return ERROR;
}
if(flag == OP_NODE)
{
tmp_node->flag = OP_NODE;
tmp_node->op = int_to_operator(num);
tmp_node->next = NULL;
if(is_stack_empty(linkStack))
{
linkStack->base = tmp_node;
linkStack->top = tmp_node;
}
else
{
tmp_node->next = linkStack->top;
linkStack->top = tmp_node;
}
}
else if(flag == DATA_NODE)
{
tmp_node->flag = DATA_NODE;
tmp_node->data = num;
tmp_node->next = NULL;
if(is_stack_empty(linkStack))
{
linkStack->base = tmp_node;
linkStack->top = tmp_node;
}
else
{
tmp_node->next = linkStack->top;
linkStack->top = tmp_node;
}
}
return OK;
}
//出栈
int pop_stack(struct LStack *linkStack)
{
struct Node *tmp_node = NULL;
if(is_stack_empty(linkStack))
{
return ERROR;
}
tmp_node = linkStack->top;
linkStack->top = linkStack->top->next;
if(linkStack->top == NULL)
{
linkStack->base = NULL;
}
free(tmp_node);
return OK;
}
//获取栈顶操作符元素,放入c中
int get_op_elem(struct LStack linkStack, char *c)
{
if(is_stack_empty(&linkStack))
{
return ERROR;
}
*c = linkStack.top->op;
return OK;
}
//获取栈顶数据元素,放入num中
int get_data_elem(struct LStack linkStack, int *num)
{
if(is_stack_empty(&linkStack))
{
return ERROR;
}
*num = linkStack.top->data;
return OK;
}
//销毁栈
int destory_stack(struct LStack *linkStack)
{
struct Node *tmp_node = NULL;
if(is_stack_empty(linkStack))
{
return OK;
}
while(linkStack->top != NULL)
{
tmp_node = linkStack->top;
linkStack->top = linkStack->top->next;
free(tmp_node);
}
linkStack->base = NULL;
return OK;
}
//获取栈的长度,将长度返回
int get_stack_length(struct LStack linkStack)
{
int length = 0;
if(is_stack_empty(&linkStack))
{
return 0;
}
while (linkStack.top != NULL)
{
linkStack.top = linkStack.top->next;
length++;
}
return length;
}
//打印栈内的数据元素
void print_stack(struct LStack linkStack)
{
printf("TOP\n");
while(linkStack.top != NULL)
{
printf("%c\n", linkStack.top->op);
linkStack.top = linkStack.top->next;
}
printf("BOTTOM\n\n");
}
//filename:function.c
#include "cal_expression.h"
/*
函数功能: 读取中缀表达式
返 回 值: 1 成功; 0 失败
*/
int get_infix(char *infix)
{
if(!infix)
{
return ERROR;
}
printf("Enter the infix expression:\n");
gets(infix);
infix[strlen(infix)] = '=';
return OK;
}
/*
函数功能: 判断字符是否为+、—、*、/、(、)等操作符
返 回 值: 1 成功; 0 失败
*/
int is_operator(char c)
{
if(c == '+' || c == '-' || c == '*' || c == '/' || c == '(' || c == ')')
{
return TRUE;
}
else
{
return FALSE;
}
}
/*
函数功能: 将整形数转化成操作符
返 回 值: 转化后的操作符
*/
char int_to_operator(int num)
{
char tmp;
switch (num)
{
case 43:
tmp = '+';
break;
case 45:
tmp = '-';
break;
case 42:
tmp = '*';
break;
case 47:
tmp = '/';
break;
case 40:
tmp = '(';
break;
case 41:
tmp = ')';
break;
}
return tmp;
}
/*
函数功能: 将栈内元素出栈,直到遇到左括号
*/
void pop_elem_until_left_bracket(struct LStack *op_stack, char *postfix, int *cont)
{
char tmp_char = '0';
get_op_elem(*op_stack, &tmp_char);
while(tmp_char != '(')
{
postfix[*cont] = tmp_char;
(*cont)++;
pop_stack(op_stack);
get_op_elem(*op_stack, &tmp_char);
}
pop_stack(op_stack);
return ;
}
/*
函数功能: 获取操作符的优先级
*/
int get_operator_priority(char c)
{
if(c == '(')
{
return 1;
}
else if(c == '+' || c == '-')
{
return 2;
}
else if(c == '*' || c == '/')
{
return 3;
}
else
{
return 0;
}
}
/*
函数功能: 弹出所有优先级大于或等于c的栈顶元素,然后将该运算符入栈
*/
void pop_high_priority_elem(struct LStack *op_stack, char op, char *postfix, int *cont)
{
char tmp_char;
get_op_elem(*op_stack, &tmp_char);
while(get_operator_priority(op) <= get_operator_priority(tmp_char))
{
postfix[*cont] = tmp_char;
(*cont)++;
pop_stack(op_stack);
if(is_stack_empty(op_stack))
{
break;
}
get_op_elem(*op_stack, &tmp_char);
}
push_stack(op_stack, op, OP_NODE);
return ;
}
/*
函数功能: 最后将栈中的所有元素弹出
*/
void all_operator_pop_stack(struct LStack *op_stack, char *postfix, int *cont)
{
char tmp_char;
while(!is_stack_empty(op_stack))
{
get_op_elem(*op_stack, &tmp_char);
postfix[*cont] = tmp_char;
(*cont)++;
pop_stack(op_stack);
}
return ;
}
int cal_result(int num_1, int num_2, char op)
{
switch(op)
{
case '+':
return (num_1 + num_2);
case '-':
return (num_2 - num_1); //区分左值和右值
case '*':
return (num_1 * num_2);
case '/':
return (num_2 / num_1);
}
return OK;
}
/*
函数功能: 将中缀表达式转换成后缀表达式
返 回 值: 1 成功; 0 失败
*/
void cal_value(struct LStack *data_struct, char operator)
{
int num_1 = 0;
int num_2 = 0;
int rslt = 0;
get_data_elem(*data_struct, &num_1);
pop_stack(data_struct);
get_data_elem(*data_struct, &num_2);
pop_stack(data_struct);
rslt = cal_result(num_1, num_2, operator);
push_stack(data_struct, rslt, DATA_NODE);
return ;
}
/*
函数功能: 将中缀表达式转换成后缀表达式
返 回 值: 1 成功; 0 失败
*/
int infix_to_postfix(char *infix, char *postfix)
{
int i = 0;
int cont = 0;
struct LStack op_stack;
init_stack(&op_stack);
while(infix[cont] != '=')
{
if(isdigit(infix[cont]))
{
postfix[i] = infix[cont];
cont++;
i++;
continue;
}
else if(is_operator(infix[cont]))
{
if(is_stack_empty(&op_stack))
{
push_stack(&op_stack, infix[cont], OP_NODE);
cont++;
continue;
}
else if(infix[cont] == '(')
{
push_stack(&op_stack, infix[cont], OP_NODE);
cont++;
continue;
}
else if(infix[cont] == ')')
{
pop_elem_until_left_bracket(&op_stack, postfix, &i);
cont++;
continue;
}
else
{
pop_high_priority_elem(&op_stack, infix[cont], postfix, &i);
cont++;
continue;
}
}
else
{
return ERROR;
}
}
all_operator_pop_stack(&op_stack, postfix, &i);
return OK;
}
/*
函数功能: 计算中缀表达式的值
参数列表: postfix 中缀表达式
result 传出参数,表达式的值
*/
int calculate_postfix(char *postfix, int *result)
{
int i = 0;
int tmp = 0;
int length = strlen(postfix);
struct LStack data_struct;
init_stack(&data_struct);
while(i != length)
{
if(isdigit(postfix[i]))
{
tmp = postfix[i] - '0';
push_stack(&data_struct, tmp, DATA_NODE);
i++;
continue;
}
else if(is_operator(postfix[i]))
{
cal_value(&data_struct, postfix[i]);
i++;
continue;;
}
}
get_data_elem(data_struct, result);
pop_stack(&data_struct);
return OK;
}
//filename:test.c
#include "cal_expression.h"
int main(int argc, char *argv[])
{
int result = 0;
char *infix = (char *)malloc(MAX_EXPRESSION_LENGTH * sizeof(char));
char *postfix = (char *)malloc(MAX_EXPRESSION_LENGTH * sizeof(char));
memset(infix, 0, MAX_EXPRESSION_LENGTH * sizeof(char));
memset(postfix, 0, MAX_EXPRESSION_LENGTH * sizeof(char));
get_infix(infix);
printf("The infix is:%s\n", infix);
infix_to_postfix(infix, postfix);
printf("The post fix is:%s\n", postfix);
calculate_postfix(postfix, &result);
printf("%s = %d\n", infix, result);
free(infix);
free(postfix);
return 0;
}