• 计算器表达式求值源码


    学习完C语言,数据结构,为了加深对知识的理解,就写了一个这样的一个小程序。

    本程序是控制台程序,开发环境为Linux,但把代码Copy下来到Windows也可以运行。

    先说一下本程序的设计思路,首先是用两个栈来存放数据和符号(数据栈和符号栈)。

    算法(重点):

    数字:数字无条件入栈
    符号:
    判断符号栈是否为空,如果为空,则无条件入栈
    如果不为空,

    当前符号如果为右括号:
    一直去弹符号栈,直到弹出第一个左括号。

    当前符号如果不为右括号:
    判读栈顶元素是不是左括号
    栈顶不是左括号
    当前符号优先级 <= 栈顶元素的优先级,则计算。(出栈一个符号,出两个数字,先出栈的数字是右操作数,后出栈的数字是左操作数)
    当前符号优先级 > 栈顶元素的优先级,符号入栈。

    栈顶是左括号
    当前符号无条件入栈

    循环结束:
    判断符号栈是否为空,如果为空,则数据栈的栈顶元素,就是最后的结果。
    如果不空,一直计算,直到符号栈为空。

    下面直接上代码:

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    //数据_结构体
    struct stack_data{
        double arr[100];
        int top;
    };
    //操作符_结构体
    struct stack_op{
        char str[100];
        int top;
    };
    //创建数据栈
    struct stack_data* create_data();
    //创建符号栈
    struct stack_op* create_op();
    //入栈
    void push_data(struct stack_data* s_d,double data);
    //入栈
    void push_op(struct stack_op* s_o,char c);
    //出栈
    double pop_data(struct stack_data* s_d);
    //出栈
    char pop_op(struct stack_op* s_o);
    //判断是否为满
    int is_full_data(struct stack_data* s_d);
    //判断是否为满
    int is_full_op(struct stack_op* s_o);
    //判断是否为空
    int is_empty_data(struct stack_data* s_d);
    //判断是否为空
    int is_empty_op(struct stack_op* s_o);
    //销毁
    void destroy_data(struct stack_data* s_d);
    //销毁
    void destroy_op(struct stack_op* s_o);
    //计算
    double compute(char c,double a,double b);
    //判断优先级
    int judge(char c);
    main(int argc,char **argv){
        struct stack_data* sd=create_data();
        struct stack_op*  so=create_op();
        char str[200];
        char *p;
        gets(str);
        for(p=str;*p;p++){
            if(*p>='0'&&*p<='9'){
                push_data(sd,atof(p));
                while(*p>='0'&&*p<='9'){
                    p++;
                }
                if(*p=='.'){
                    p=p+1;
                    while(*p>='0'&&*p<='9')p++;
                }
                p--;
            }else{
                if(is_empty_op(so)||*p=='('){
                    push_op(so,*p);
                    continue;
                }else{
                    if(*p==')'){
                        while(so->str[so->top-1]!='('){
                                char b1=pop_op(so);
                                double a1=pop_data(sd);
                                double a2=pop_data(sd);
                                push_data(sd,compute(b1,a1,a2));
                        }
                        pop_op(so);
                    }else{
                        if(so->str[so->top-1]!='('){
                            if(judge(*p)<=judge(so->str[so->top-1])){
                                char b2=pop_op(so);
                                double a3=pop_data(sd);
                                double a4=pop_data(sd);
                                push_data(sd,compute(b2,a3,a4));
                                p--;
                                continue;
                            }else{
                                push_op(so,*p);
                            }
                        }else{
                            push_op(so,*p);
                        }
                    }
                }
            }    
        }
        while(is_empty_op(so)==0){
            char b3=pop_op(so);
            double a5=pop_data(sd);
            double a6=pop_data(sd);
            push_data(sd,compute(b3,a5,a6));
        }
        while(is_empty_data(sd)==0){
            printf("%f ",pop_data(sd));
        }
        destroy_data(sd);
        sd=NULL;
        destroy_op(so);
        so=NULL;
        return 0;
    }
    //创建数据栈
    struct stack_data* create_data(){
        struct stack_data* s=malloc(sizeof(*s));
        memset(s,0,sizeof(*s));
        s->top=0;
    }
    //创建符号栈
    struct stack_op* create_op(){
        struct stack_op* s=malloc(sizeof(*s));
        memset(s,0,sizeof(*s));
        s->top=0;
    }
    //入栈
    void push_data(struct stack_data* s_d,double data){
         s_d->arr[s_d->top]=data;
        s_d->top+=1;
    }
    //入栈
    void push_op(struct stack_op* s_o,char c){
        s_o->str[s_o->top]=c;
        s_o->top+=1;
    }
    //出栈
    double pop_data(struct stack_data* s_d){
        s_d->top-=1;
        double data=s_d->arr[s_d->top];
        return data;
    }
    //出栈
    char pop_op(struct stack_op* s_o){
        s_o->top-=1;
        char c=s_o->str[s_o->top];
        return c;
    }
    //判断是否为满
    int is_full_data(struct stack_data* s_d){
        if(s_d->top==100)
            return 1;
        return 0;
    }
    //判断是否为满
    int is_full_op(struct stack_op* s_o){
        if(s_o->top==100)
            return 1;
        return 0;
    }
    //判断是否为空
    int is_empty_data(struct stack_data* s_d){
        if(s_d->top==0)
            return 1;
        return 0;
    }
    //判断是否为空
    int is_empty_op(struct stack_op* s_o){
        if(s_o->top==0)
            return 1;
        return 0;
    }
    //销毁
    void destroy_data(struct stack_data* s_d){
        free(s_d);
        s_d=NULL;
    }
    //销毁
    void destroy_op(struct stack_op* s_o){
        free(s_o);
        s_o=NULL;
    }
    //计算
    double compute(char c,double a,double b){
        if(c=='+')return b+a;
        if(c=='-')return b-a;
        if(c=='*')return b*a;
        if(c=='/')return b/a;
    }
    //判断优先级
    int judge(char c){
        if(c=='+'||c=='-')
            return -1;
        if(c=='*'||c=='/')
            return 0;
    }

    这是初级版本,只能算加减乘除和带括号的表达式,支持小数,以后会更新。

    希望和大家多交流,分享。

  • 相关阅读:
    通信接收机同步模块
    CAZAC序列
    Verilog Tricks
    载波同步
    Matlab step方法
    CRC校验码
    比特冗余
    Vivado RAM使用
    collection
    hashlib
  • 原文地址:https://www.cnblogs.com/wzqstudy/p/9474890.html
Copyright © 2020-2023  润新知