简单逻辑实现一个计算器,没有用到树的知识

这篇博客记录了作者实现一个简单计算器的过程,重点在于如何处理括号的配对,利用栈的数据结构来实现。当遇到左括号时存储,遇到右括号时与最近的左括号匹配并计算,最后用新操作数替换。文中用C语言实现了这一逻辑,通过栈操作回顾了栈的应用。
摘要由CSDN通过智能技术生成

/*

这几天想整理一下自己所学,就想写一些简单的东西,就想到实现一个简单的计算器


1. 输入的每个计算数必须是整数,且长度不超过10
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[
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值