带括号有负数有小数有表达式的计算器的简单实现

//

//  main.cpp

//  c++计算器

//

//  Created by student on 14-5-11.

//  Copyright (c) 2014 student. All rights reserved.

//


#include<stdio.h>

#include<math.h>

#include<stdlib.h>

#define MAX 1000


struct save1

{

    float n[MAX];

    int top;

}stack1;


struct save2

{

    char n[MAX];

    int top;

}stack2;

//stack1存储数字,stack2存储运算符号.


bool stackempty(save1 s)//判断是否为空

{

    if (s.top== -1)

        return 1;

    else

        return 0;

}


bool stackempty2(save2 s)//判断是否为空

{

    if (s.top== -1)

        return 1;

    else

        return 0;

}


void push(save1 &s,float e)//e入栈

{

    if(s.top==MAX-1)

    {

        printf("栈已满!/n");

        return ;

    }

    s.top++;

    s.n[s.top]=e;

}


void push2(save2 &s,char e)//e入栈

{

    if(s.top==MAX-1)

    {

        printf("栈已满!/n");

        return ;

    }

    s.top++;

    s.n[s.top]=e;

}


void pop(save1 &s,float &e)//将栈顶元素出栈,存到e

{

    if(s.top==-1)

    {

        printf("栈为空!/n");

    }

    else

    {e=s.n[s.top]; s.top--; }

}


void pop2(save2 &s,char &e)//将栈顶元素出栈,存到e

{

    if(s.top==-1)

    {  printf("栈为空!/n"); }

    else

    {e=s.n[s.top]; s.top--; }

}


int in(char e)//e在栈内的优先级别

{

    if(e=='-' || e=='+') return 2;

    if(e=='*' || e=='/') return 4;

    if(e=='^') return 5;

    if(e=='(') return 0;

    if(e==')') return 7;

    return -1;

}


char precede(char ch1,char ch2)

{

    char op[]="+-*/()^";

    int i;

    int j;

    char table[7][8]={

        

        "<<<<><<",

        "<<<<><<",

        ">><<><<",

        ">><<><<",

        ">>>>>=>",

        "<<<<=<<",

        ">>>>><>"

    };

    for (i=0; i<7; i++) if(op[i]==ch2)break;

    for (j=0; j<7; j++) if(op[j]==ch1)break;

    return table[i][j];

}


int out(char e)//e在栈外的优先级别

{

    if(e=='-' || e=='+') return 1;

    if(e=='*' || e=='/') return 3;

    if(e=='^') return 6;

    if(e=='(') return 7;

    if(e==')') return 0;

    return -1;

}


void count(float a,char ope,float b)

{

    float sum;

    if(ope=='+') sum=a+b;

    if(ope=='-') sum=a-b;

    if(ope=='*') sum=a*b;

    if(ope=='/') sum=a/b;

    if(ope=='^') sum=pow(a,b);

    push(stack1,sum);

}


bool isdigit(char a)

{

    if('0'<=a && a<='9')

        return 1;

    else

        return 0;

}


bool isalpha(char c)

{

    if (('a'<=c && c<='z') ||('A'<=c && c<='Z')) {

        return 1;

    }

    return 0;

}

int main()

{

    int i=0,len=0,j,nofpoint,g=0;//len表示输入式子的长度。 g表示读入的字符是否是字母变量、数字以及运算符。

    float a,b;//ab用来存储操作数栈中弹出的操作数,便于代入函数中进行计算。

    char line[MAX],operate,temp[20];

    scanf("%s",line);

    while (line[len++]!='\0');

   // len=(int)strlen(line);

    len--;

    stack1.top=-1;//将栈置为空

    stack2.top=-1;//将栈置为空

    while(1)

    {

        g=0;

        if('0'<=line[i] && line[i]<='9')//若读入的字符为数字,则继续判断下一个字符,直到下一个字符不是数字或者不是小数点,即可保证该操作数是完整的小数,然后将该数入操作数栈。

        {

            j=0; g=1;

            nofpoint=0;//记录所存的数中小数点的个数

            while(('0'<=line[i] && line[i]<='9') || line[i]=='.')

            {

                if(line[i]=='.') nofpoint++;

                temp[j++]=line[i];

                i++;

                if(i>=len) break;

            }

            if( nofpoint>1 || (i<len&&(line[i]!='-' && line[i]!='+' && line[i]!='*' && line[i]!='/' && line[i]!='^' && line[i]!=')')) )

            { printf("表达式有错\n"); return 0; }//所存数中含有不止一个小数点,或者数字后面跟的不是“+-*/^)”,则为错误

            

            temp[j]='\0';

            b=atof(temp);

            push(stack1,b);

            if(i>=len) break;

        }

        else

        {

            if(line[i]=='-' || line[i]=='+' || line[i]=='*' || line[i]=='/' ||

               line[i]=='^' || line[i]=='(' || line[i]==')' ) //若读入的字符为运算符的情况

            {

                g=1;

                if(line[i]=='(' && i==len) { printf("表达式有错\n"); return 0; }// “(”放表达式最后面,错误

                if(line[i]=='-' || line[i]=='+' || line[i]=='*' || line[i]=='/' || line[i]=='^')

                {

                    if(i==len) { printf("表达式有错\n"); return 0; }//“+-*/^”放在表达式最后面,错误

                    if( (!isdigit(line[i+1])) && (!isalpha(line[i+1])) && line[i+1]!='(')//“+-*/^”后面跟的不是数字或者变量,错误

                    { printf("表达式有错\n"); return 0; }

                }

                

                if(line[i]=='-' && (i==0 || line[i-1]=='(' ))//运算符是负号

                {

                    push(stack1,0);

                    push2(stack2,line[i]);

                    i++;

                }

                else

                { //读入的运算符与运算符栈的栈顶元素相比,并进行相应的操作

                    if(in(stack2.n[stack2.top])<out(line[i])||stackempty2(stack2))

                    //if((precede(stack2.n[stack2.top], line[i])=='>')|| stackempty2(stack2))

                    {

                        push2(stack2,line[i]);i++;

                    }

                    else

                        if(in(stack2.n[stack2.top])==out(line[i]))

                        //if(precede(stack2.n[stack2.top], line[i])=='=')

                        {

                            i++; stack2.top--;

                        }

                        else 

                            if(in(stack2.n[stack2.top])>out(line[i]))

                            //if (precede(stack2.n[stack2.top], line[i])=='<')

                            { 

                                pop(stack1,a); 

                                pop(stack1,b); 

                                pop2(stack2,operate); 

                                count(b,operate,a); 

                            } 

                    if(i>=len) break

                } 

            } 

            else 

            { 

                if(isalpha(line[i]))//读入的字符是字母变量的情况 

                { 

                    g=1; 

                    printf("请输入变量");

                    while( isalpha(line[i])) { printf("%c",line[i]); i++; }

                    printf("的值\n");

                    scanf("%f",&b);

                    push(stack1,b); 

                    if(i>=len) break

                    if(line[i]!='-' && line[i]!='+' && line[i]!='*' && line[i]!='/' && line[i]!='^' && line[i]!=')')//变量后面跟的不是“+-*/^)”,则为错误 

                    { printf("表达式有错\n"); return 0; }

                }

            } 

        } 

        if(g==0) { printf("表达式有错\n"); return 0; }//g=0表示该字符是不符合要求的字符

    } 

    

    while(stack2.top!=-1)//读入结束后,继续进行操作,直到运算符栈为空 

    { 

        pop(stack1,a); 

        pop(stack1,b); 

        pop2(stack2,operate); 

        if(operate=='(' || operate==')') //括号多余的情况 

        { printf("表达式有错\n"); return 0; }

        count(b,operate,a); 

    } 

    printf("%.f\n",stack1.n[stack1.top]);

    return 0; 

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值