zoukankan      html  css  js  c++  java
  • C:算术表达式求值

    代码:

    // fgets2.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    typedef enum{
        TT_NUM,
        TT_ADD,
        TT_SUB,
        TT_MUL,
        TT_DIV,
        TT_LP,
        TT_RP,
        TT_EOL
    }TokenType;
    
    typedef struct{
        TokenType type;
        char text[255];
    }Token;
    
    static int pos=0;
    static char* line;
    
    static Token prevToken;
    static int prevTokenExist;
    
    
    
    void getToken(Token *token){
        char arr[255];
        int index=0;
        arr[index]='';
    
        while(line[pos]!=''){    
            if(line[pos]=='+'){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    
                    return;
                }
    
                token->text[0]='+';
                token->text[1]='';
                token->type=TT_ADD;
                pos++;
                return;
            }else if(line[pos]=='-'){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    return;
                }
    
                token->text[0]='-';
                token->text[1]='';
                token->type=TT_SUB;
                pos++;
                return;
            }else if(line[pos]=='*'){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    return;
                }
    
                token->text[0]='*';
                token->text[1]='';
                token->type=TT_MUL;
                pos++;
                return;
            }else if(line[pos]=='/'){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    return;
                }
    
                token->text[0]='/';
                token->text[1]='';
                token->type=TT_DIV;
                pos++;
                return;
            }else if(line[pos]=='('){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    return;
                }
    
                token->text[0]='(';
                token->text[1]='';
                token->type=TT_LP;
                pos++;
                return;
            }else if(line[pos]==')'){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    return;
                }
    
                token->text[0]=')';
                token->text[1]='';
                token->type=TT_RP;
                pos++;
                return;
            }else if(line[pos]=='
    '){
                if(strlen(arr)>0){
                    strcpy(token->text,arr);
                    index=0;
                    arr[index]='';
                    token->type=TT_NUM;
                    return;
                }
    
                token->text[0]='';
                token->type=TT_EOL;
                pos++;
                return;
            }else{
                arr[index]=line[pos];
                index++;
                arr[index]='';
                pos++;
            }        
        }
    
        if(strlen(arr)>0){
            strcpy(token->text,arr);
            index=0;
            arr[index]='';
            token->type=TT_NUM;
            return;
        }
    }
    
    void fetchToken(Token *token){
        if(prevTokenExist){
            *token=prevToken;
            prevTokenExist=0;
        }else{
            getToken(token);
        }
    }
    
    void returnToken(Token *token){
        prevToken=*token;
        prevTokenExist=1;
    }
    
    char* getTokenTypeDesc(Token *token){
        char* arr;
        arr = (char *)malloc(100); 
    
        if(token->type==0){
            strcpy(arr,"Num");
        }else if(token->type==1){
            strcpy(arr,"Add");
        }else if(token->type==2){
            strcpy(arr,"Sub");
        }else if(token->type==3){
            strcpy(arr,"Mul");
        }else if(token->type==4){
            strcpy(arr,"Div");
        }else if(token->type==5){
            strcpy(arr,"LP");
        }else if(token->type==6){
            strcpy(arr,"RP");
        }
    
        return arr;
    }
    
    double parse_expression(void); // 为了防止出现 “找不到标识符parse_expression”
    
    static  double parse_primary_expression(){
        Token token;
    
        fetchToken(&token);
        if(token.type==TT_NUM){
            return atof(token.text); // 字符串转double
        }else if(token.type==TT_LP){
            double value=parse_expression();
            fetchToken(&token);
            if(token.type!=TT_RP){
                printf("missing ).");
                exit(1);
            }
            return value;
        }else{
            returnToken(&token);
            return 0;
        }
    
        return 0;
    }
    
    static double parse_term(){
        double v1;
        double v2;
        Token token;
    
        v1=parse_primary_expression();
    
        for(;;){
            fetchToken(&token);
    
            if(token.type!=TT_MUL && token.type!=TT_DIV){
                returnToken(&token);
                break;
            }
    
            v2=parse_primary_expression();
            if(token.type==TT_MUL){
                v1*=v2;
            }else if(token.type==TT_DIV){
                v1/=v2;
            }else{
                returnToken(&token);
            }
        }
    
        return v1;
    }
    
    static double parse_expression(){
        double v1;
        double v2;
        Token token;
    
        v1=parse_term();
    
        for(;;){
            fetchToken(&token);
    
            if(token.type!=TT_ADD && token.type!=TT_SUB){
                returnToken(&token);
                break;
            }
    
            v2=parse_term();
            if(token.type==TT_ADD){
                v1+=v2;
            }else if(token.type==TT_SUB){
                v1-=v2;
            }else{
                returnToken(&token);
            }
        }
    
        return v1;
    }
    
    double parse(){
        prevTokenExist=0;
        return parse_expression();
    }
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        char buf[1024];
    
        while(fgets(buf,1024,stdin)!=NULL){
            pos=0;
            line=buf;
            printf("=%f
    ",parse());
        }
        return 0;
    }

    输出:

    1+(2+3)*4
    =21.000000
    (1+2)/5-4*(6-7)
    =4.600000
    12*12-12*10
    =24.000000

    --2020年6月6日--

  • 相关阅读:
    Vue插件之导出EXCEl
    vue.js--加载JSON文件的两种方式
    vue项目中axios的封装
    雪碧图布局
    开始学习算法
    Java中有关Null的9件事
    一个抓取知乎页面图片的简单爬虫
    浅析Java中的final关键字
    Java中String、StringBuilder以及StringBuffer
    把一个数组向右循环移动k位要求时间复杂度为O(n)
  • 原文地址:https://www.cnblogs.com/heyang78/p/13056221.html
Copyright © 2011-2022 走看看