首先,將中綴表達式轉換成後綴表達式,用壓棧的方法:
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;
}