zoukankan      html  css  js  c++  java
  • 使用后缀表达式写的数据结构实验,实现计算器

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

    自己写的可以实现简单的‘+-*/’运算以及包括‘() [] {} 指数 小数 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 != '=');
    }
  • 相关阅读:
    iOS resign code with App Store profile and post to AppStore
    HTTPS科普扫盲帖 对称加密 非对称加密
    appid 评价
    使用Carthage安装第三方Swift库
    AngularJS:何时应该使用Directive、Controller、Service?
    xcode7 The operation couldn't be completed.
    cocoapods pod install 安装报错 is not used in any concrete target
    xcode7 NSAppTransportSecurity
    learning uboot how to set ddr parameter in qca4531 cpu
    learning uboot enable protect console
  • 原文地址:https://www.cnblogs.com/reddusty/p/4945595.html
Copyright © 2011-2022 走看看