/*
这几天想整理一下自己所学,就想写一些简单的东西,就想到实现一个简单的计算器
2. 整个表达式的长度不超过256
3. 不考虑异常输入,保证每个输入都是合法的
4. 操作符只包含()*/+-
5. 优先级,()最高,*/次之,+-最低
最开始的思路:
1. 区分操作数operand与操作符operator;
2. 每个操作符都会有一个左操作数与右操作数
3. 相邻的操作符之间会有一个优先级,通过比较可以取出其中一个操作符先计算,然后将计算出的结果作为一个新的操作数
4. 替换(),遍历的时候先去掉(),即如果遇到(,则遍历字符串直到),然后将这些内容取出,作为一个整体计算出结果,作为一个新的操作数
按照开始的思路的话,可以声明2个数组,一个用来存放操作数,一个用来存放操作符,这里数组大小也是个问题;
A)开始遍历
-->>a.如果是数字,存储到一个临时数组,继续遍历,直到遇到一个非数字为止,然后将给临时数组转换为整数,存放进操作数数组
-->>b.如果是操作符
-->>c.不是(,第一次肯定先存储到操作符数组,如果操作符数组非空的话,则在存储前先与上一个操作符比较,
如果优先级比上一个高(*/ > +-),则继续读取,如果低(+- < */),则先取出上一个操作符,同时从操作数数组中取出
2个操作数,生成一个新操作数存入操作数数组,并将这个操作符存入操作符数组;
-->>d.且是(,则继续遍历,直到),将读取到的字符串放到一个临时数组,然后计算该字符串的结果作为一个新操作数
存入到操作数数组
B)一直遍历,最后可以发现剩下的操作符数组中,都是前面的操作符优先级小于后面的操作符,此时我们就可以倒序计算结果
好吧,这时发现如果有嵌套()的话,上面的思路d就不适用了。
考虑到()是成对就近匹配的,即最近的一个()是一对,再想一下,即)跟离它最近的一个(是一对,好吧,精确匹配的话,遇到(的时候,我们可以先存储起来,直到遇到),然后依次取出直到遇到第一个(,然后计算替换成一个新操作数存储起来;
下面贴出的是具体实现代码,可以发现使用stack替换成array,数组的存储、取出的操作对应stack的push、pop;
这里不是说stack比数组好用,而是为了回忆一下stack的用法与实现;
这里的stack也非常简单,类型都是固定了,int,char,如果通用的话,可能就会用到void *;
*/#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUM 256
#define OPD_MAX_LEN 10
#ifdef __DEBUG
#define DBG_PRINT printf
#else
#define DBG_PRINT(fmt, ...)
#endif
typedef struct _optStack
{
char opt[MAX_NUM];
int top;
} optStack;
typedef struct _opdStack
{
int opd[MAX_NUM];
int top;
} opdStack;
optStack optSt;
opdStack opdSt;
void initOptSt()
{
optSt.top = -1;
}
void initOpdSt()
{
opdSt.top = -1;
}
int isOptEmpty()
{
if (-1 == optSt.top)
{
return 1;
}
return 0;
}
char getLastOpt()
{
DBG_PRINT("--->>%d optSt.top:%d\n", __LINE__, optSt.top);
return optSt.opt[optSt.top];
}
int getLastOpd()
{
return opdSt.opd[opdSt.top];
}
int isOpdEmpty()
{
if (-1 == opdSt.top)
{
return 1;
}
return 0;
}
void pushOpt(char c)
{
optSt.top++;
optSt.opt[