用栈实现简易计算器c++

该博客介绍了如何使用C++编程语言实现一个简单的计算器,支持基本的加减乘除及括号运算。代码中包含详细注释,尽管存在一些不足之处,作者欢迎读者提出指导建议。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目前只支持+-*/以及英文的()的简单运算

详情见注释

//easy caculator
//
//Created by zzx on 2018.10.10
#include <iostream>
using namespace std;
#include <string>
#include <stdlib.h>

#define MaxSize 100
char precede(char a, char b);
template <class T>
class stack {
private:
		int top;
		T data[MaxSize] = { 0 };
public:	
	void intstack(stack <T> *s)//初始化栈
	{
		s->top = 0;
	}
	int isEmpty(stack<T> *s)//判断栈空
	{
		if (s->top == 0)
		{
			return 0;
		}
		return 1;
	}
	int isfull(stack <T> *s)//判断栈满
	{
		if (s->top == MaxSize)
			return 0;
		return 1;
	}
	int push(stack <T> *s, T x)//进栈
	{
		if (!isfull(s))
		{
			return -1;
		}
		else
		{
			if (!isEmpty(s))
				top = 0;
			s->top++;
			s->data[s->top - 1] = x;
		}
		return 0;
	}
	T pop(stack <T> *s)//栈顶元素出栈 
	{
		if (!isEmpty(s))
			return -1;
		else
		{
			T x;
			x = s->data[s->top - 1];
			s->top--;
			return x;
		}
	}
	T gettop(stack <T> *s)//取出栈顶元素
	{
		if (!isEmpty(s))
			return -1;
		else
		{
			T x;
			x = s->data[s->top - 1];
			return x;
		}
	}
};
/*
【函数名】calc
【函数功能】计算表达式
【参数】a被操作数
【参数】c运算符
【参数】b被操作数
*/
double calc(double b, char c, double a)
{
	double result;
	switch (c)
	{
	case '+':
		result = a + b; break;
	case '-':
		result = a - b; break;
	case '*':
		result = a * b; break;
	case '/':
		result = a / b; break;
	default:
		cout << "calc函数计算出错" << endl;
		return -1;
	}
	return result;
}
/*
【函数名】 解析表达式
【参数str[]】输入的字符串
【参数a】操作数栈地址
【参数b】运算符地址
*/
int parse(char str[], stack <double> *a, stack <char> *b)//解析表达式
{
	char dou[MaxSize] = { 0 };
	double result = 0;
	for (int i = 0; str[i] != '\0'; i++)//如果字符串不为'\0'则继续循环
	{
		char c = str[i];
		if (c >= '0'&&c <= '9' || c == '.')
		{		//处理操作数
			char t[20] = { 0 };//建立个储存单个数据的数组
			int j=0;
			for ( j = 0; str[i + j] >= '0'&&str[i + j] <= '9' || str[i + j] == '.'; j++)
			//遇到数据字符时提取后面字符直到遇到运算符
			{
				t[j] = str[i + j];
			}
			t[j] = '\0';
			i = i + j - 1;//更新i

			double value = atof(t);//将字符串数组压缩为浮点型
			(*a).push(a, value);

		}
		else
		{		//处理运算符
			if (!(*b).isEmpty(b))//判断是否为空  空为真
			{
				(*b).push(b, c);
			}
			else
			{
				char op = 0;
				double num1 = 0;
				double num2 = 0;
				op = (*b).gettop(b);//取栈顶元素
				op = precede(op, c);
				switch (op)
				{
				case '<':(*b).push(b, c); break;//优先级高于栈顶元素,直接入栈
				case '=':(*b).pop(b); break;//弹出左括号
				case '>'://退栈并进行计算将结果存放到操作数栈
					//运算符继续进行比较					
					num1 = (*a).pop(a);
					num2 = (*a).pop(a);
					op = (*b).pop(b);
					result = calc(num1, op, num2);
					(*a).push(a, result);
					i--;//保证括号与其它运算符结合时正确
					break;
				default:
					cout << "表达式解析出错,可能是输入了错误符号:(" << endl << endl;
					return -1;
				}
			}			
		}
	}

	while ((*b).isEmpty(b))
	{
		char op = 0;
		double num1 = 0;
		double num2 = 0;
		num1 = (*a).pop(a);
		num2 = (*a).pop(a);
		op = (*b).pop(b);
		result = calc(num1, op, num2);
		(*a).push(a, result);
	}
	if (!(*b).isEmpty(b))
		result = (*a).pop(a);
	if (!(*a).isEmpty(a))
	{
		cout << ":)表达式计算结果为(最多保存小数点后六位):" << result << endl << endl;	
		return 0;
	}
	cout << "erroring!\n";
}
char precede(char a, char b)//比较运算符的优先级
{
	char prior_table[6][6] = {//按运算优先级制表
		//+   -   *   /   (   )
		{'>','>','<','<','<','>'},//+加号
	{'>','>','<','<','<','>'},//-减号
	{'>','>','>','>','<','>'},//*乘号
	{'>','>','>','>','<','>'},// /除号
	{'<','<','<','<','<','='},// (左括号
	{ '>','>','>','>','>','>' }// )右括号
	};
	int x = -1;
	int y = -1;
	char opr[] = "+-*/()";
	for (int i = 0; i < 6; i++)//遍历二维数组查找对应的运算关系
	{
		if (a == opr[i])x = i;
		if (b == opr[i])y = i;
	}
	return prior_table[x][y];
}

int main()
{
	while (1)
	{
		stack<double>  num_stack;
		stack<char>  str_stack;//将类模板的数据类型定义好
		num_stack.intstack(&num_stack);
		str_stack.intstack(&str_stack);
		cout << "************************************" << endl;
		cout << ":) 请输入表达式:\n";
		char str[MaxSize] = { 0 };
		cin >> str;
		parse(str, &num_stack, &str_stack);
	}
	system("pause");
	return 0;
}

很多地方略有拙劣,望指教

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值