c++实现简单计算器

  试着用c++写了一个计算器,支持加减乘除和括号。

  我是分步完成的,先写了一个简单的不支持括号的,然后再改成支持括号版。

一. 仅支持加减乘除

  用两个手写栈(不推荐stl的栈,因为栈不难写,stl感觉太慢),一个栈存储符号,一个栈存储已经读入的数(无符号)。

  扫一遍表达式,把符号和数字按次序存进两个栈(注意,如果第一个数是正数,则第一个进栈的符号要是+号;如果是负数,则进栈一个-号,存储数的栈则存进正数)。存储符号的栈只需要存储+和-就行了,如果读到了*或\号,就直接乘除给栈顶的数,这样可以保证乘除的优先级。

  扫完了之后按顺序算一遍栈就行了。

#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=10000;

int n;
char ch[maxn+5];

int read_pos;    //read()读入时最后一个字符的位置+1 
inline int read(int s){    //返回以ch[s]为开头的数 
    int ans=0;
    for (;(ch[s]>='0'&&ch[s]<='9');s++)
        ans=ans*10+ch[s]-'0';
    read_pos=s;
    return ans;
}

int solve(int l,int r){    //表达式l到r的值 
    int stack[2][maxn+5],len=0;    //手写栈 
    if (ch[l]!='-')
        stack[0][++len]=1,stack[1][len]=read(l);
    else stack[0][++len]=-1,stack[1][len]=read(l+1);
    l=read_pos;
    int temp;
    while (l<=r){
        if (ch[l]=='+')
            stack[0][++len]=1,stack[1][len]=read(l+1);
        else if (ch[l]=='-')
            stack[0][++len]=-1,stack[1][len]=read(l+1);
        else if (ch[l]=='*')
            temp=read(l+1),stack[1][len]*=temp;
        else temp=read(l+1),stack[1][len]/=temp;
        l=read_pos;
    }
    int result=0;
    for (int i=1;i<=len;i++)    //处理掉栈中的数 
        result+=(stack[0][i]*stack[1][i]);
    return result;
}

int main(){
//    freopen("test2.in","r",stdin);
    scanf("%s",ch);
    int tt=strlen(ch);
    printf("%d",solve(0,tt-1));
    return 0;
}

二. 支持括号

  应该有很多种模拟方法,我是在预处理时存进每一对括号的位置,然后递归计算括号就行了(把括号当数来看)。

#include <cstdio>
#include <cstring>
using namespace std;
const int maxn=10000;

int n;
char ch[maxn+5];
int to[maxn+5];

int que[maxn+5],size;

int read_pos;

int read(int s);

int solve(int l,int r){
    int stack[2][maxn+5],len=0;
    if (ch[l]!='-')
        stack[0][++len]=1,stack[1][len]=read(l);
    else stack[0][++len]=-1,stack[1][len]=read(l+1);
    l=read_pos;
    int temp;
    while (l<=r){
        if (ch[l]=='+')
            stack[0][++len]=1,stack[1][len]=read(l+1);
        else if (ch[l]=='-')
            stack[0][++len]=-1,stack[1][len]=read(l+1);
        else if (ch[l]=='*')
            temp=read(l+1),stack[1][len]*=temp;
        else    temp=read(l+1),stack[1][len]/=temp;
        l=read_pos;
    }
    int result=0;
    for (int i=1;i<=len;i++)
        result+=(stack[0][i]*stack[1][i]);
    return result;
}

int main(){
//    freopen("test2.in","r",stdin);
    scanf("%s",ch);
    int tt=strlen(ch);
    for (int i=0;i<tt;i++)
        if (ch[i]=='(')
            que[++size]=i;
        else if (ch[i]==')')
            to[que[size]]=i,size-=1;
    printf("%d",solve(0,tt-1));
    return 0;
}


inline int read(int s){
    int ans=0,f=1;
    if (ch[s]=='('){
        ans=solve(s+1,to[s]-1);
        read_pos=to[s]+1;
        return ans;
    }
    else if (ch[s]=='-') f=-1,s+=1;
    for (;(ch[s]>='0'&&ch[s]<='9');s++)
        ans=ans*10+ch[s]-'0';
    read_pos=s;
    return ans*f;
}

猜你喜欢

转载自www.cnblogs.com/awakening-orz/p/11265694.html
今日推荐