计算中缀表达式的值

首先,将中缀表达式转换成后缀表达式,用压栈的方法:

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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值