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

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

自己写的可以实现简单的‘+-*/’运算以及包括‘() [] {} 指数 小数 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\n");

                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\n",tail_expression->data);

        return 0;
}

//判断是不是操作符
bool is_op(char *op)
{
        if ((*op) == '+' || (*op) == '-'|| (*op) == '*' || (*op) == '/' || (*op) == '('
        || (*op) == ')' || (*op) == '[' || (*op) == ']' || (*op) == '{' || (*op) == '}'
        || (*op) == '^' || (*op) == '=' || (*op) == '\n')
                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("输入有误\n");
                        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 \n");
                        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 == '\n') 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] = '\0';
                                //操作符入栈
                                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 != '=');
}

 

posted @ 2015-11-07 16:26  孙悟坑  阅读(628)  评论(0编辑  收藏  举报