码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-11-07 17:43:00      阅读:325      评论:0      收藏:0      [点我收藏+]

标签:

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

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

 

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

标签:

原文地址:http://www.cnblogs.com/reddusty/p/4945595.html

(0)
(1)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!