【数据结构】用栈实现的简单计算器(先转换为后缀表达式、可以计算带括号的)

先将中缀表达式转化成后缀表达式

再计算后缀表达式

计算后缀表达式的规则:从左到右遍历表达式的每个数字和符号,遇到是数字就进栈,遇到是符号,就将处于栈顶的两个数字出栈,进行运算,运算结果进栈,一直到最终获得结果。

代码 C++:VS2013 + WIN7

#include <iostream>
using namespace std;

#define ok 0
#define error -1

typedef int Elemtype;
typedef int status;//函数返回的状态,如ok  error

typedef struct StackNode
{
	Elemtype data;
	struct StackNode *next;
}StackNode, *StackNodeP;

typedef struct LinkStack
{
	StackNodeP top;
	int count;
}LinkStack;

LinkStack* LinkStack_Create();//链栈的创建
status LinkStack_Clear(LinkStack* stack);//链栈的清空
int LinkStack_Isempty(LinkStack* stack);//链栈是否为空
status LinkStack_Push(LinkStack* stack, Elemtype e);//链栈的入栈
Elemtype LinkStack_Pop(LinkStack* stack);//链栈的出栈
int LinkStack_Length(LinkStack* stack);//链栈的长度
Elemtype LinkStack_Top(LinkStack* stack);//链栈的头部元素

status change(char* buf, char* afterbuf)
{
	int i = 0;
	LinkStack* LS = LinkStack_Create();
	/*
	设定
	(   -1
	+   1
	-   2
	*   3
	/   4
	*/
	while (*buf)
	{
		if ((*buf >= '0') && (*buf <= '9'))
		{
			while ((*buf >= '0') && (*buf <= '9'))
			{
				afterbuf[i] = *buf;
				buf++;
				i++;
			}
			afterbuf[i++] = ',';
		}
		if (*buf == '+')
		{
			if (LinkStack_Isempty(LS))//如果链栈为空,则直接将‘+’入栈
				LinkStack_Push(LS, 1);
			else if (LinkStack_Top(LS)> 2)//如果链栈的头结点上为‘*’‘/’,则栈中所有都弹出
			{
				while (!LinkStack_Isempty(LS))//直到将栈中的所有都弹出
				{
					if (LinkStack_Top(LS) == -1)//如果为'('则停止循环
					{
						break;
					}
					else
					{
						switch (LinkStack_Top(LS))
						{
						case 1:
							afterbuf[i++] = '+'; afterbuf[i++] = ','; break;
						case 2:
							afterbuf[i++] = '-'; afterbuf[i++] = ','; break;
						case 3:
							afterbuf[i++] = '*'; afterbuf[i++] = ','; break;
						case 4:
							afterbuf[i++] = '/'; afterbuf[i++] = ','; break;
						}
					}
					LinkStack_Pop(LS);
				}
				LinkStack_Push(LS, 1);
			}
			else//如果链栈中也是‘+’‘-’则直接入栈
				LinkStack_Push(LS, 1);
			buf++;
		}
		if (*buf == '-')
		{
			if (LinkStack_Isempty(LS))//如果链栈为空,则直接将‘+’入栈
				LinkStack_Push(LS, 2);
			else if (LinkStack_Top(LS)> 2)//如果链栈的头结点上为‘*’‘/’,则栈中所有都弹出
			{
				while (!LinkStack_Isempty(LS))//直到将栈中的所有都弹出
				{
					if (LinkStack_Top(LS) == -1)//如果为'('则停止循环
					{
						break;
					}
					else
					{
						switch (LinkStack_Top(LS))
						{
						case 1:
							afterbuf[i++] = '+'; afterbuf[i++] = ','; break;
						case 2:
							afterbuf[i++] = '-'; afterbuf[i++] = ','; break;
						case 3:
							afterbuf[i++] = '*'; afterbuf[i++] = ','; break;
						case 4:
							afterbuf[i++] = '/'; afterbuf[i++] = ','; break;
						}
					}
					LinkStack_Pop(LS);
				}
				LinkStack_Push(LS, 2);
			}
			else//如果链栈中也是‘+’‘-’则直接入栈
				LinkStack_Push(LS, 2);
			buf++;
		}
		if (*buf == '*')//如果为'*'直接入栈
		{
			LinkStack_Push(LS, 3);
			buf++;
		}
		if (*buf == '/')//如果为'/'直接入栈
		{
			LinkStack_Push(LS, 4);
			buf++;
		}
		if (*buf == '(')//如果为左括号则直接进栈
		{
			LinkStack_Push(LS, -1);
			buf++;
		}
		if (*buf == ')')//如果为右括号则出栈直到左括号
		{
			while (LinkStack_Top(LS) != -1)
			{
				switch (LinkStack_Top(LS))
				{
				case 1:
					afterbuf[i++] = '+'; afterbuf[i++] = ','; break;
				case 2:
					afterbuf[i++] = '-'; afterbuf[i++] = ','; break;
				case 3:
					afterbuf[i++] = '*'; afterbuf[i++] = ','; break;
				case 4:
					afterbuf[i++] = '/'; afterbuf[i++] = ','; break;
				}
				LinkStack_Pop(LS);
			}
			LinkStack_Pop(LS);//最后把左括号给弹出来
			buf++;
		}
	}
	while (!LinkStack_Isempty(LS))
	{
		switch (LinkStack_Top(LS))
		{
		case 1:
			afterbuf[i++] = '+'; afterbuf[i++] = ','; break;
		case 2:
			afterbuf[i++] = '-'; afterbuf[i++] = ','; break;
		case 3:
			afterbuf[i++] = '*'; afterbuf[i++] = ','; break;
		case 4:
			afterbuf[i++] = '/'; afterbuf[i++] = ','; break;
		}
		LinkStack_Pop(LS);
	}
	return NULL;
}

int calculate(char* array)
{
	int result = 0;//用来保存计算结果
	int a, b;
	char buf[10] = { 0 };
	int i = 0;
	LinkStack* LS = LinkStack_Create();//创建一个栈
	while (*array)
	{
		if ((*array >= '0') && (*array <= '9'))
		{
			while ((*array >= '0') && (*array <= '9'))//检测多少位数
			{
				buf[i] = *array;
				i++;
				array++;
			}
			LinkStack_Push(LS, atoi(buf));//将数字入栈
			memset(buf, 0, sizeof(buf));
			i = 0;
		}
		if (*array == '+')
		{
			a = LinkStack_Pop(LS);//取出栈顶元素
			b = LinkStack_Pop(LS);//取出栈顶元素
			result = b + a;
			LinkStack_Push(LS, result);//再将计算结果入栈
		}
		if (*array == '-')
		{
			a = LinkStack_Pop(LS);
			b = LinkStack_Pop(LS);
			result = b - a;
			LinkStack_Push(LS, result);
		}
		if (*array == '*')
		{
			a = LinkStack_Pop(LS);
			b = LinkStack_Pop(LS);
			result = b * a;
			LinkStack_Push(LS, result);
		}
		if (*array == '/')
		{
			a = LinkStack_Pop(LS);
			b = LinkStack_Pop(LS);
			result = b / a;
			LinkStack_Push(LS, result);
		}
		array++;
	}
	return result;
}

int main(void)
{
	char* buf = (char*)malloc(sizeof(char));
	char afterbuf[1024] = { 0 };
	cin >> buf;
	change(buf, afterbuf);//中缀表达式转后缀表达式
	cout << "转换的后缀表达式为:" << afterbuf << endl;
	int result = calculate(afterbuf);//用后缀表达式来计算
	cout << "计算结果为:" << result << endl;
	system("pause");
}

//链栈的创建
LinkStack* LinkStack_Create()
{
	LinkStack* temp = NULL;
	temp = (LinkStack*)malloc(sizeof(LinkStack));
	if (temp == NULL)
		cout << "LinkStack_create 出错" << endl;
	temp->count = 0;
	temp->top = NULL;
	return temp;
}
//链栈的清空
status LinkStack_Clear(LinkStack* stack)
{
	if (stack == NULL)
		return ok;
	stack->top->next = NULL;
	stack->count = 0;
	return ok;
}
//链栈是否为空
int LinkStack_Isempty(LinkStack* stack)
{
	if (stack == NULL)
		return error;
	return stack->top == NULL ? 1 : 0;
}

//链栈的长度
int LinkStack_Length(LinkStack* stack)
{
	if (stack == NULL)
		return error;
	return stack->count;
}
//链栈的入栈
status LinkStack_Push(LinkStack* stack, Elemtype e)
{
	if (stack == NULL)
		return error;
	LinkStack* temp = NULL;
	temp = (LinkStack*)stack;

	StackNodeP SNP = (StackNodeP)malloc(sizeof(StackNode));
	SNP->data = e;
	SNP->next = temp->top;
	temp->top = SNP;

	temp->count++;
	return ok;
}
//链栈的出栈
Elemtype LinkStack_Pop(LinkStack* stack)
{
	if (stack == NULL)
		return error;
	LinkStack* temp = NULL;
	temp = (LinkStack*)stack;
	Elemtype node = temp->top->data;//这是将要删除的元素缓存下来
	StackNodeP p = temp->top;//将栈顶结点赋值给p
	temp->top = temp->top->next;//栈顶指针下移一位,指向后一个结点
	free(p);//释放结点

	temp->count--;
	return node;
}
//链栈的头部元素
Elemtype LinkStack_Top(LinkStack* stack)
{
	if (stack == NULL)
		return error;

	return stack->top->data;
}


执行结果图:



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值