栈的应用---中缀转后缀

该博客介绍了如何将中缀表达式转换为后缀表达式,并利用后缀表达式进行计算。转换过程中涉及到了栈操作,如遇到数字直接输出,遇到运算符则与栈顶符号比较优先级。计算时,遍历后缀表达式,依次将数字入栈,遇到运算符则弹出栈顶的两个数字进行运算并将结果压回栈。最后,栈中的唯一数字即为计算结果。
摘要由CSDN通过智能技术生成

思路:

遍历中缀表达式中的数字和符号:

对于数字:直接输出
对于符号:
左括号:进栈
运算符号:与栈顶符号进行优先级比较

左括号:进栈
运算符号:与栈顶符号进行优先级比较


若栈顶符号优先级低:此符号进栈(默认栈顶若是左括号,左括号优先级最低)

若栈顶符号优先级不低;将栈顶符号弹出并输出,之后进栈


右括号:将栈顶符号弹出并输出,直到匹配左括号
遍历结束:将栈中的所有符号弹出并输出

后缀表达式计算

遍历后缀表达式中的数字和符号

对于数字:进栈
对于符号:
       从栈中弹出右操作数

       从接中弹出左操作数

根据符号进行运算

将运算结果压入栈中
遍历结束:栈中的唯一数字为计算结果

 8+(3-1)*5的计算

Infix_Variable_Suffix.h 

#define _CRT_SECURE_NO_WARNINGS
#include "Chain_Stack.h"
#include <ctype.h>



//转换
int priority(char c);

void output(char c);

bool is_Left(char c);

bool is_Right(char c);

bool isOperator(char c);

void transform(const char* exp);


//计算
int express(int left, int right, char op);

int* Value(char c);

int compute(const char*exp);


char str[10] = { 0 };
char *buff = str;
int *arr[100] = { 0 };
int count = 0;

 

.cpp

#include "Infix_Variable_Suffix.h"


//转换
int priority(char c)
{
	int ret = 0;
	if (c == '+' || c == '-')
	{
		ret = 1;
	}
	if (c == '*' || c == '/')
	{
		ret = 2;
	}
	return ret;
}

void output(char c)
{
	if (c != '\0')
	{
		printf("%c", c);
		sprintf(buff++, "%c", c);
	}
}

bool is_Left(char c)
{
	return c == '(';
}

bool is_Right(char c)
{
	return c == ')';
}

bool isOperator(char c)
{
	return (c == '+') || (c == '-') || (c == '*') || (c == '/');
}

void transform(const char *exp)
{
	assert(exp != NULL);
	int i = 0;
	LinkStack *stack = LinkStack_Create();
	while (exp[i] != '\0')
	{
		if (isdigit(exp[i]))//直接输出数字
		{
			output(exp[i]);
		}
		else if (isOperator(exp[i])) //操作符入栈
		{
			if (LinkStack_Top(stack) != NULL)
			{
				while (priority(exp[i]) <= priority(*(char*)LinkStack_Top(stack)))
				{
					output(*(char*)LinkStack_Pop(stack));
				}
			 LinkStack_Push(stack, (void*)(exp + i));
			}
			else
			{
				LinkStack_Push(stack, (void*)(exp + i));
			}
		
		}
		else if (is_Left(exp[i]))  //左括号入栈
		{
			LinkStack_Push(stack, (void*)(exp + i));
		}
		else if (is_Right(exp[i]))
		{
			while (!is_Left(*(char*)LinkStack_Top(stack)))
			{
				output(*(char*)LinkStack_Pop(stack));
			}
			LinkStack_Pop(stack); //左括号出栈
		}
		else
		{
			printf("Invalid expression!");
			break;
		}
		i++;
	}
	while (LinkStack_Size(stack) > 0 && exp[i] == '\0')
	{
		output(*(char*)LinkStack_Pop(stack));
	}
	printf("\n");
	LinkStack_Destroy(stack);
}




//计算
int express(int left, int right, char op)
{
	int ret = 0;
	switch (op)
	{
	case '+':
		ret = left + right;
		break;
	case '-':
		ret = left - right;
		break;
	case '*':
		ret = left*right;
		break;
	case '/':
		ret = left / right;
		break;
	default:
		break;
	}
	return ret;
}

int* Value(char c)
{
	
	int *a = (int*)malloc(sizeof(int));
	*a = c - '0';
	arr[count++] = a;
	return a;
}

int compute(const char*exp)
{
	LinkStack *stack = LinkStack_Create();
	int i = 0;
	
	while (exp[i] != '\0')
	{
		if (isdigit(exp[i]))  //数字直接入栈
		{
			LinkStack_Push(stack, (void*)Value(exp[i]));
		}
		else if (isOperator(exp[i]))   //如果是运算符,从栈中提取两个数
		{
			int right = *(int*)LinkStack_Pop(stack); 
			int left = *(int*)LinkStack_Pop(stack); 

			int result = express(left, right, exp[i]);
			LinkStack_Push(stack, (void*)&result);   //计算结果入栈
		}
		else
		{
			printf("Invalid expression!");
			break;
		}
		i++;
	}
	int ret = 0;
	if (LinkStack_Size(stack) == 1 && exp[i] == '\0')
	{
		ret = *(int*)LinkStack_Pop(stack);
	}
	else
	{
		printf("Invalid expression!");
	}
	LinkStack_Destroy(stack);
	return ret;
}

main.cpp

int main()
{
	transform("8+(3-1)*5");
	int result = compute(str);
	printf("%d\n", result);
	for (int i = 0; i < count; i++)
	{
		free(arr[i]);
	}
	_CrtDumpMemoryLeaks();

	system("pause");
	return 0;
}

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值