项目3:算术表达式求解

【问题描述】 设计一个简单的算术表达式计算器。

【基本要求】  实现标准整数类型的四则运算表达式的求值(包含括号,可多层嵌入).

【测试数据】 (30+2*70)/3-12*3  5+(9*(62-37)+15)*6  要求自行设计非法表达式,进行程序测试,以保证程序的稳定运行。

【实现提示】 可以设计以下辅助函数 status isNumber(char ReadInChar);  //视ReadInchar 是否是数字而返回 TRUE 或 FALSE 。 int TurnToInteger(char IntChar);   // 将字符’0’.’9’ 转换为整数 9

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<map>
#include<iomanip>
#include<ctype.h>
#include"calculate.h"
#define INF 99999999
using namespace std;
 
const int MAX=10;
 
typedef struct stack{
    int *date;//存大数 
    char ch;
    int mark;//mark用来标记符号:正负
    stack *next;
    stack(){
        next=NULL,mark=1;
    }
};
 
typedef struct head{
    stack *top;
    int size;
    head(){
        top=NULL,size=0;
    }
    void push(stack* &p);
    void Clear();
    void Pop();
};
head stack_dou,stack_ch;//一个用来存数字,一个用来存运算符.
 
void output(stack* &p){
    cout<<"结果是:";
    int l=p->date[0];
    if(p->date[l] != 0 && p->mark == -1)cout<<"-";
    cout<<p->date[l];
    for(int i=l-1;i>=1;--i)cout<<setfill('0')<<setw(4)<<p->date[i];
    cout<<endl;
}
 
bool isoperator(char s){//判断运算符s是否符合条件. 
    if(s == '+' || s == '-' || s == '*' || s == '/' || s == '(' || s == ')')return true;
    return false;
}
 
void head::push(stack* &p){//元素入栈. 
    p->next=this->top;
    this->top=p;
    this->size++;
}
 
void head::Pop(){//删除栈顶元素. 
    stack *p=this->top;
    this->top=this->top->next;
    this->size--;
    delete p;
}
 
void head::Clear(){//清空栈. 
    while(this->top){
        stack *p=this->top;
        this->top=this->top->next;
        delete p;
    }
    this->size=0;
}
 
bool stack_dou_calculate(char s){//s代表运算符,对实数栈的栈顶两个元素进行运算. 
    if(stack_dou.size<2)return false;
    int *second=stack_dou.top->date,mark2=stack_dou.top->mark;
    stack_dou.top->date=NULL;stack_dou.Pop();
    int *first=stack_dou.top->date,mark1=stack_dou.top->mark;
    stack_dou.top->date=NULL;stack_dou.Pop();
    int *sum=new int[100];
    if(s == '+' && mark1*mark2 == 1 || 
      (s == '-' && mark1*mark2 == -1))add(first,second,sum);//相加 
    if(s == '-' && mark1*mark2 == 1){//相减 
        if(cmp(first,second))sub(first,second,sum);
        else {sub(second,first,sum);mark1=-1*mark2;}
    }
    if(s == '+' && mark1*mark2 == -1){//相减 
        if(cmp(first,second))sub(first,second,sum);
        else {sub(second,first,sum);mark1=mark2;}
    }
    if(s == '*')mult(first,second,sum);//相乘 
    if(s == '/')div(first,second,sum);//相除 
    stack *p=new stack;
    p->date=sum;
    p->mark=mark1;
    stack_dou.push(p);
    delete first;
    delete second;
    return true;
}
 
bool cmp(char a,char b){//比较运算符a,b的优先级. 
    if(b == '+' || b == '-' || a== '*' || a == '/' || b == ')' || a == '(')return true;
    return false;
}
 
void calculate(string s){//计算表达式s. 
    string a;
    for(int i=0;i<s.size();++i){
        if(s[i] == ' '){if(a.size()){stack *p=new stack;p->date=new int[100];trans(a,p->date);stack_dou.push(p);a.clear();}continue;}
         if(isdigit(s[i]))a+=s[i];
        else if(isoperator(s[i])){
            if(a.size()){stack *p=new stack;p->date=new int[100];trans(a,p->date);stack_dou.push(p);a.clear();}
            while(stack_ch.top && cmp(stack_ch.top->ch,s[i])){
                if(stack_ch.top->ch != '('){
                    if(!stack_dou_calculate(stack_ch.top->ch))break;
                    stack_ch.Pop();
                }
                else {stack_ch.Pop();break;}
            }
            if(s[i] != ')'){stack *p=new stack;p->ch=s[i];stack_ch.push(p);}
        }
        else{cout<<"输入错误,请重输!\n";return;}
    }
    if(a.size()){stack *p=new stack;p->date=new int[100];trans(a,p->date);stack_dou.push(p);a.clear();}
    while(stack_ch.top){
        if(!stack_dou_calculate(stack_ch.top->ch))break;
        stack_ch.Pop();
    }
    if(stack_dou.size == 1 && stack_ch.size == 0)
        output(stack_dou.top);
    else cout<<"输入错误,请重输!\n";
}
 
int main(){
    string s;
    cout<<"请输入表达式:";
    while(getline(cin,s)){//输入表达式s. 
        calculate(s);//计算表达式s. 
        stack_dou.Clear();//清空实数栈. 
        stack_ch.Clear();//清空字符栈.
        cout<<"请输入表达式:"; 
    }
    return 0;
}

calculate.h:

#include<cstring>
#include<string>
using namespace std;
 

const int Base=10000,seg=4;

void trans(string ch,int *s){//将字符串转化为数字 
    int i,k=1;
    int L=ch.size()-seg; 
    for(i=L;i>=0;i-=seg,k++){//从字符串后面开始,依次四位四位存入整型数组.
        s[k]=ch[i]-'0';
        for(int j=i+1;j<i+seg;++j){
            s[k]=s[k]*10+ch[j]-'0';
        }
    }
    i+=seg;
    s[k]=0;
    for(int j=0;j<i;++j){
        s[k]=s[k]*10+ch[j]-'0';
    }
    if(s[k])s[0]=k;//s[0]储存该数组的位数. 
    else s[0]=k-1;
}

 
void add(int *A,int *B,int *sum){//大整数相加 
    int la=max(A[0],B[0]),i,c=0;
    for(int i=A[0]+1;i<=la;++i)A[i]=0;
    for(int i=B[0]+1;i<=la;++i)B[i]=0;
    for(i=1;i<=la;++i){
        sum[i]=A[i]+B[i]+c;
        if(sum[i]>=Base){
            c=sum[i]/Base;
            sum[i]%=Base;
        }else c=0;
    }
    if(c>0){
        sum[i]=c;
        sum[0]=i;
    }
    else sum[0]=i-1;
}

 
void sub(int *A,int *B,int *sum){//大数相减 
    int c=0;
    for(int i=B[0]+1;i<=A[0];++i)B[i]=0;
    for(int i=1;i<=A[0];++i){
        sum[i]=A[i]-B[i]+c;
        if(sum[i]<0){
            sum[i]+=Base;
            c=-1;
        }else c=0;
    }
    sum[0]=1;
    for(int i=A[0];i>=1;--i){
        if(sum[i]){
            sum[0]=i;
            break;
        }
    }
}

 
void mult(int *A,int *B,int *sum){//大整数相乘 
    int i,j,k;
    int all=A[0]+B[0]-1;
    memset(sum,0,sizeof(int)*(all+3));
    for(i=1,k=1;i<=A[0];++i){
        k=i;
        if(A[i]){
            for(j=1;j<=B[0];++j,++k){
                sum[k]+=A[i]*B[j];
                if(sum[k]>=Base){
                   sum[k+1]+=sum[k]/Base;
                   sum[k]=sum[k]%Base;    
                }
            }
        }
    }
    while(sum[k]>=Base){
        sum[k+1]+=sum[k]/Base;
        sum[k]=sum[k++]%Base;
    }
    if(!sum[k])k--;
    sum[0]=k;
}

 
//比较a,b的大小 
bool cmp(int *a,int *b){
    if(a[0]>b[0])return true;
    if(a[0]<b[0])return false;
    for(int i=a[0];i>=1;--i){
        if(a[i]>b[i])return true;
        if(a[i]<b[i])return false;
    }
    return true;
}
 
//比较a从第t个位置开始和b的大小
int cmp(int *a,int *b,int t){
    int i,j=1;
    for(i=b[0];i>=1;--i,++j){
        if(a[t]>b[i])return j;
        if(a[t]<b[i])return -1;
        --t;
    }
    return 0;

 
void copy(int *a,int *b){
    a[0]=b[0];
    for(int i=1;i<=a[0];++i)a[i]=b[i];
}
 
int zero[]={1,0};
 
//sum=a/b,r=a%b
void div(int *a,int *b,int *sum/*,int *r*/){//大整数除法 
    int m=a[0],n=b[0];
    int Base1000=Base*1000,Base100=Base*100,Base10=Base*10;
    if(!cmp(a,b)){
        /*copy(r,a),*/copy(sum,zero);
        return;
    }
    int k=m-n+1;
    for(int i=k;i>=0;--i)sum[i]=0;
    for(int i=k,t=m;i>=1,t>=n;){
        int p=cmp(a,b,t);//a[t]-b[n]
        if(p<0 && t == n)break;
        if(p == 0){
            sum[i]++;
            for(int j=t;j>=t-n+1;--j)a[j]=0;
            t-=n;
            if(t<n)break;
            i-=n;
        }
        if(p>1){
            sum[i]++;
            for(int j=t,q=n;j>=t-n+1;--j,--q)a[j]-=b[q];
            for(int j=t-n+1;j<=t;++j){
                if(a[j]<0){
                    a[j]+=Base,a[j+1]--;
                }
            }
            int j;
            for(int j=t;j>=t-n+1;--j)if(a[j])break;
            if(j<n)break;
            i-=(t-j);
            t=j;
        }
        if(p<0 && t>n){
            a[t-1]+=a[t]*Base;
            a[t]=0;
            --t;
            --i;
        }
        if(p == 1){
            int x=a[t]/(b[n]+1);
            sum[i]+=x;
            for(int j=t,q=n;q>=1;--q,--j)a[j]-=x*b[q];
            for(int j=t-n+1;j<=t;++j){
                while(a[j]<=-Base1000){a[j]+=Base1000,a[j+1]-=1000;}
                while(a[j]<=-Base100){a[j]+=Base100,a[j+1]-=100;}
                while(a[j]<=-Base10){a[j]+=Base10,a[j+1]-=10;}
                while(a[j]<=0){a[j]+=Base,a[j+1]-=1;}
            }
        }
    }
    if(sum[k] == 0)sum[0]=k-1;else sum[0]=k;
    /*int i;
    for(i=m;i>=1;--i)if(a[i])break;
    if(i == 0)copy(r,zero);
    else{
        r[0]=i;
        while(i >= 1)r[i]=a[i--];
    }
}
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值