表达式计算器

1+2/3*(4-6)*6/8+9*2 = ?

#include <stdio.h>
#include <stdlib.h>

#define 	MAXSIZE		32
typedef struct{
	int data[MAXSIZE];//数据段
	int top;//栈指针
}sqstack;

sqstack *sqstack_create()
{
	sqstack *sq;
	sq = malloc(sizeof(*sq));
	if(sq == NULL )
	{
		return NULL;
	}
	sq->top = -1;
	return sq;
}

int sqstack_push(sqstack *sq, int *data)//入栈
{
	if(sq->top == MAXSIZE-1)//full
	{
		return -1;
	}
	else
	{
		sq->data[++sq->top] = *data;
	}
	return 0;
}

int sqstack_top(sqstack *sq, int *data)//取得栈顶数据
{
	if(sq->top == -1)//empty
	{
		return -1;
	}
	*data = sq->data[sq->top];
	return 0;
}

int sqstack_pop(sqstack *sq, int *data)//出栈
{
	if(sq->top == -1)//empty
	{
		return -1;
	}
	*data = sq->data[sq->top--];
	return 0;
}

int compute(sqstack *snum, int ope)
{
	int n1, n2, n;
	sqstack_pop(snum, &n1);
	sqstack_pop(snum, &n2);
	switch(ope)
	{
		case '+':	n=n1+n2; printf("%d+%d=%d\n", n1, n2, n); break;
		case '-':	n=n2-n1; printf("%d-%d=%d\n", n2, n1, n);break;
		case '*':	n=n1*n2; printf("%d*%d=%d\n", n1, n2, n);break;
		case '/':	n=n2/n1; printf("%d/%d=%d\n", n2, n1, n);break;
		default:
			return -1;//break;
	}
	sqstack_push(snum, &n);//将运算结果压入数字栈
	return 0;
}

void deal_bracket(sqstack *snum, sqstack *sope)//处理括号
{
	int old_ope;
	sqstack_top(sope, &old_ope);//取得栈顶运算符
	while(old_ope != '(')
	{
		sqstack_pop(sope, &old_ope);
		compute(snum, old_ope);
		sqstack_top(sope, &old_ope);//取得栈顶运算符
	}
	sqstack_pop(sope, &old_ope);
}

int sqstack_is_empty(sqstack *sq)
{
	return (sq->top == -1);
}

int get_pri(int ope)
{
	switch(ope)
	{
		case '(':	return 0;
		case '+':
		case '-':	return 1;
		case '*':
		case '/':	return 2;
	}
}
void deal_ope(sqstack *snum, sqstack *sope, int ope)//处理运算符
{
	int old_ope;
	if(ope == '('||sqstack_is_empty(sope))
	{
		sqstack_push(sope, &ope);
		return ;
	}
	sqstack_top(sope, &old_ope);
	if(get_pri(ope) > get_pri(old_ope))
	{
		sqstack_push(sope, &ope);
		return ;
	}
	while(get_pri(ope) <= get_pri(old_ope))// * +
	{
		sqstack_pop(sope,&old_ope);
		compute(snum,old_ope);
		if(sqstack_is_empty(sope))
			break;
		sqstack_top(sope,&old_ope);
	}
	sqstack_push(sope,&ope);
}

int main()
{
	sqstack *snum;//运算数字栈
	sqstack *sope;//运算符栈
	int i = 0, value = 0, flag = 0, old_ope;

	char str[] = "1+3-(2*5)*(8-6)+5";//所要计算的表达式
	//初始化
	snum = sqstack_create();
	sope = sqstack_create();

	while(str[i] != '\0')
	{
		if(str[i] >= '0' && str[i] <= '9')//数字
		{
			value = value*10 + str[i]-'0';
			flag = 1;
		}
		else//运算符
		{
			if(flag == 1)//取得了运算的数字
			{
				sqstack_push(snum, &value);//数字入 运算数字栈
				value = 0;
				flag = 0;
			}
			if(str[i] == ')')
			{
				deal_bracket(snum,sope);
			}
			else//(+-*/
			{
				deal_ope(snum,sope,str[i]);
			}
		}
		i++;
	}
	if(flag)
	{
		sqstack_push(snum,&value);
	}
	while(!sqstack_is_empty(sope))
	{
		sqstack_pop(sope, &old_ope);
		compute(snum, old_ope);
	}
	sqstack_pop(snum, &value);

	printf("%s = %d\n", str, value);
	return 0;
}
时间: 2024-08-06 14:41:40

表达式计算器的相关文章

表达式计算器类的设计5(面向对象的表达式计算器8)

计算器的github下载地址:https://github.com/ljian1992/calculator 概述 表达式计算器的类基本已经设计完成了,由于在程序运行的时候总会有这样那样的异常,例如:a +2, a没有初始化,对于异常的管理一般而言是需要自定义异常类.这个自定义异常类也是在继承了系统已经定义好的exception类,然后再重新定义内容. 异常的种类 语法异常---->SyntaxError类 赋值时左操作数不是变量:1 = 2; 缺少括号:1 + (2*2 不认识的函数: 函数缺

表达式计算器类的设计4(面向对象的表达式计算器7)

概述 把符号表和变量表中的内容保存到一个文件中,通过IO文件流,来把符号表和变量表存储到文件中.在这之前需要弄明白什么是序列化和反序列化 对象的序列化 序列化:把对象转换为字节序列的过程 反序列化:把字节序列恢复为对象的过程 我们要把SymbolTable类的对象(符号表)和Storage类的对象(变量表)转换成字节序列保存到文件中,这时就可以设置Serializer类来完成这样的功能,同样的设置一个DeSerializer类来完成把保存到文件当中的字节序列恢复为对象的功能.这里要注意的是,所有

表达式计算器类的设计3(面向对象的表达式计算器6)

概述 有了构建语法的类,存储符号的类,现在就可以对表达式进行扫描,解析了.扫描可以抽象出一个Scanner类来完成这一个功能,而解析可以抽象出一个Parser类来完成这一个功能.这两个类存在一定的关系,扫描与解析的互动是这样子的:扫描到一个标识符,然后解析它是什么标识符.由于该表达式计算器是要支持一些命令的,命令的解析和表达式的解析过程完全不一样,所有呢,又要设置一个CommandParser类,来解析命令. Scanner类,Parser类,CommandParser类的设计 Scanner类

表达式计算器类的设计2(表达式计算器5)

计算器的github下载地址:https://github.com/ljian1992/calculator 符号表,函数表,变量存储表 表达式计算器,需要支持变量和函数,而变量和函数都是些符号,因此设置一个SymbolTable类来存储这些符号.符号有两种,一种是变量,一种是函数,故在设置一个Storage类存储变量中的值,设置一个FunctionTable类来存储函数.由于这三中类存在着联系,现在在设置一个Calc类来管理它们. SymbolTable类,FunctionTable类,Sto

基于对象编程与面向对象编程(表达式计算器3)

基于对象编程与面向对象编程 我们的最终目的是用C++设计一个面向对象的表达式计算器,所以非常有必要弄清楚,什么是基于对象编程和面向对象的编程.而要弄清楚这一点,又要先弄明白什么是值语言,什么是对象语义 值语义:对象的拷贝与原对象无关,拷贝后与原对象脱离关系,互不影响.这种拷贝叫深拷贝.拷贝之后脱离关系,只要在拷贝的时候都为对象分配内存空间就行了.某种些情况下算是一种对资源的浪费 值语义例子 class Test { private: int * pNum_; public: Test(int n

表达式计算器类的设计1(表达式计算器4)

计算器的github下载地址:https://github.com/ljian1992/calculator 我们的最终目的是计算出表达式中的值,因此就需要定义一个抽象类用于计算表达式的值,该抽象类定义为:Node 下面所有的类图不使用UML建模语言画的,是通过visual studio自动生成的类关系图(自己用UML建模画的不小心被我删掉了) Node的类图 它继承了个Noncpyable类,由于我们是要做面向对象的表达式计算器,所以呢,通过一个小小的手段,把拷贝给禁止掉.这个小小的手段就是让

【APP】表达式计算器 更新说明

下载链接(包括源代码):http://pan.baidu.com/s/1kTwrhcV 更新日志: 版本号:1.0.0.3 更新时间:2014/07/02 12:52 --修复了mv命令和rm命令的一些Bug 该Bug通常会导致出现不寻常的错误 --修复了赋值表达式中直接输入:=的错误 该Bug会导致程序崩溃 版本号:1.0.0.2 更新时间:2014/07/02 01:08 --修复了自定义变量名称的一些Bug 该Bug通常会导致不能正常处理变量名而出错 --修复了判断传入参数的消息映射系统的

Flex版本的基于栈的表达式计算器

/** * 表达式计算器,输入数学表达式的字符串,输出计算结果的数值 * 1.扫描表达式,将运算符与运算数分别入栈, * 2.运算符入栈前先与上一个运算符进行优先级比较,如果当前运算符优先级低于或等于前一个运算符, * 则将前一个运算符和对应的运算数出栈运算,否则运算符直接入栈 * @author lijy */ public class ExpressionCaculator { /** * 运算数栈 * */ private var numberStack:Array; /** * 运算符栈

VS2013 调试时出现“表达式计算器中发生内部错误”的问题解决办法

今天写代码的时候跟踪程序,发现打断点的地方根本看不到断点变量的结果,而且在快速监视中显示“ 表达式计算器中发生内部错误 ”,更看不到监视的变量了,上网找了半天也没找到答案,后来重新分析了一下自己的代码,发现是因为代码内部有死循环造成的,倒不是自己写的死循环,是有几个checkbox(我是在winform程序中)控件我添加了CheckedChanged事件方法,比如说这个事件方法我们暂且叫它FunctionA(“这个方法内部有设置类的枚举变量B的代码”),而我在Form_Load方法中又通过这个类

基于语法分析器GOLD Parser开发的数学表达式计算器

最近发现一款文法分析神器,看完官网(http://goldparser.org/)的介绍后感觉很犀利的样子,于是就拿来测试了一番,写了一个数学表达式分析的小程序,支持的数学运算符如下所示:常规运算:+ - * / ^ sqrt sqrt2(a,b) pow2(a) pow(a,b)三角函数:sin cos tan cot asin acos atan acot指数对数:log2(a) log10(a) ln(a) logn(a,b) e^最大最小:max(a,b,...) min(a,b,...