• 使用后缀表达式写的数据结构实验,实现计算器


    数据结构实验需要使用后缀表达式进行计算的设计

    自己写的可以实现简单的‘+-*/’运算以及包括‘() [] {} 指数 小数 2e3’等的运算,用于交作业,功能很少,代码如下

    #include <stdio.h>
    #include <stdlib.h>
    #include <malloc.h>
    #include <stdbool.h>
    #include <math.h>
    //定义操作数的最大位数
    #define MAX 64
    
    typedef struct element {
            char data[MAX];
            struct element * pre;
            struct element * next;
    } ELE;
    
    //用来判断是否是操作符
    bool is_op(char *op);
    //判断优先级
    bool is_high(char *op);
    //操作符进入操作符栈
    void push_op_to_opstack(char op);
    //压入后缀表达式操作符即计算
    void push_op_to_expression(char *op);
    //压入后缀表达式操作数
    void push_num_to_expression(void);
    //操作符栈下标
    static int OP_INDEX = 0;
    //操作符栈
    char op_stack[MAX];
    //表达式的头
    ELE * expression_header = NULL;
    //尾节点
    ELE * tail_expression = NULL;
    //新节点
    ELE * node;
    
    int main(void)
    {
            //为表达式头节点分配内存并初始化
            expression_header = (ELE *)malloc(sizeof(ELE));
            if (expression_header == NULL)
            {
                    printf("Error
    ");
    
                    return 0;
            }
            else
            {
                    expression_header->data[0] = '#';
                    expression_header->next = NULL;
                    expression_header->pre = NULL;
            }
    
            push_num_to_expression();
    
             //所有的操作符出栈
            while(OP_INDEX > 0)
            {
                    push_op_to_expression(&op_stack[OP_INDEX-1]);
                    OP_INDEX--;
            }
            printf("计算结果%s
    ",tail_expression->data);
    
            return 0;
    }
    
    //判断是不是操作符
    bool is_op(char *op)
    {
            if ((*op) == '+' || (*op) == '-'|| (*op) == '*' || (*op) == '/' || (*op) == '('
            || (*op) == ')' || (*op) == '[' || (*op) == ']' || (*op) == '{' || (*op) == '}'
            || (*op) == '^' || (*op) == '=' || (*op) == '
    ')
                    return true;
            return false;
    }
    
    //判断操作符的优先级
    bool is_high(char *op)
    {
           if (OP_INDEX == 0) return false;
           //只需要将规则写入这里
           if ((op_stack[OP_INDEX-1] == '+') && (*op == '+' || *op == '-')) return true;
           if ((op_stack[OP_INDEX-1] == '-') && (*op == '+' || *op == '-')) return true;
           if ((op_stack[OP_INDEX-1] == '*') && (*op == '+' || *op == '-' || *op == '*' || *op == '/')) return true;
           if ((op_stack[OP_INDEX-1] == '/') && (*op == '+' || *op == '-' || *op == '*' || *op == '/')) return true;
           if ((op_stack[OP_INDEX-1] == '^') && (*op == '+' || *op == '-' || *op == '*' || *op == '/' || *op == '^')) return true;//最大的规则
           if (*op == ')' || *op == ']' || *op == '}' || *op == '=') return true;
           return false;
    }
    
    //操作符进入操作符栈
    void push_op_to_opstack(char op)
    {
            if (OP_INDEX == 0)
            {
                    op_stack[OP_INDEX] = op;
                    OP_INDEX++;
                    return;
            }
            else
            {
                    //判断优先级
                    while (is_high(&op))
                    {
                            if (op_stack[OP_INDEX-1] == '(' || op_stack[OP_INDEX-1] == '['
                            || op_stack[OP_INDEX-1] == '{') break;
                            //当前操作符栈顶的操作符进入后缀表达式
                            push_op_to_expression(&op_stack[OP_INDEX-1]);
                            //当前操作符指针减1
                            OP_INDEX--;
                    }
    
                    //如果是括号,或者是中括号,就将之前的括号或中括号去掉
                    if (op == ')' || op == ']' || op == '}' || op == '=')
                    {
                            OP_INDEX--;
    
                            return;
                    }
    
                    //读入的操作符入栈
                    op_stack[OP_INDEX] = op;
                    //指针自加一
                    OP_INDEX++;
    
                    return;
            }
    }
    
    //将操作符压入栈中,即进行计算
    //其实不用压栈,直接将弹出的操作符加入后最表达式队列进行计算
    void push_op_to_expression(char *op)
    {
            double last_number;
            double first_number;
    
            if (*op == '=') return;
            last_number = atof(tail_expression->data);
            //释放内存
            tail_expression = tail_expression->pre;
            free(tail_expression->next);
            tail_expression->next = NULL;
            first_number = atof(tail_expression->data);
    
            switch ((*op))
            {
                    case '+':
                            first_number += last_number;
                            break;
                    case '-':
                            first_number -= last_number;
                            break;
                    case '*':
                            first_number *= last_number;
                            break;
                    case '/':
                            first_number /= last_number;
                            break;
                    case '^':
                            first_number = pow(first_number, last_number);
                            break;
                    default:
                            printf("输入有误
    ");
                            exit(0);
                            break;
            }
            //将计算的结果存回字符数组
            sprintf(tail_expression->data, "%f", first_number);
    }
    
    void push_num_to_expression(void)
    {
            char c;
            int i;
    
            do
            {
                    i = 0;
                    node = (ELE *)malloc(sizeof(ELE));
    
                    if (node == NULL)
                    {
                            printf("Error 
    ");
                            return;
                    }
    
                    //将链表连接
                    if (expression_header->next == NULL)
                    {
                            expression_header->next = node;
                            node->pre = expression_header;
                            node->next = NULL;
                            tail_expression = node;
                    }
                    else
                    {
                            tail_expression->next = node;
                            node->pre = tail_expression;
                            node->next = NULL;
                            tail_expression = node;
                    }
    
                    //开始输入
                    do
                    {
                            c = getchar();
                            if (c == '
    ') c = '=';
                            //如果是操作符
                            if (is_op(&c))
                            {
                                    if (i == 0)
                                    {
                                            //如果第一个是操作符,删除此节点
                                            //操作符入栈
                                            tail_expression = node->pre;
                                            free(tail_expression->next);
                                            tail_expression->next = NULL;
                                            push_op_to_opstack(c);
                                            break;
                                    }
                                    //添加结束符
                                    node->data[i] = '';
                                    //操作符入栈
                                    push_op_to_opstack(c);
    
                                    break;
                            }
                            else
                            if ((c >= '0' && c <= '9') || c == '.' || c == 'e')
                            {
                                    node->data[i] = c;
                                    i++;
                            }
                            else
                            if ( c == '=') break;
                    }while(1);
    
            }while(c != '=');
    }
  • 相关阅读:
    【Objective-C学习笔记】变量和基本的数据类型
    数据文件实时同步(rsync + sersync2)
    入园自述
    软件工程人才的社会需求现状与发展趋势分析
    ERP-安心卡功能
    银盒宝成APP下载地址
    关于新商家后台添加商品后,一体机上不显示分类问题解决流程
    各类型商户微信认证方法
    网商微信实名认证FAQ
    扫码下单支持同桌单人点餐FAQ
  • 原文地址:https://www.cnblogs.com/reddusty/p/4945595.html
Copyright © 2020-2023  润新知