栈的运用(不带括号的加减乘除)

例如计算 2+3*4-1/5
这个式子,在计算机中如和那代码实现
首先明白整体的思路:
这里由操作数和运算符,所以这里我们要创建两个栈,来分别充当操作数栈和运算符栈,好,现在创建栈。
栈的特点是先进后出,这里我们创建一个结构体
在这里插入图片描述
这里把top当成一个指示标志,来记数,这里设置了data数组的最大内存容量是10,所以看下图,这里需要对我们上面定义的结构体初始化。初始化为-1,后面再++时,可以和数组下标对上,当top=9时说明栈已经满了
在这里插入图片描述
top初始化的函数
在这里插入图片描述
这里需要创建两个栈,一个时运算符的栈,一个是操作数的栈。
当我们栈创建好,并且分配好空间,我们就可以输入计算的式子,进行判断了,刚开始两个栈里都是空栈,去输入的字符,判断是操作数还是运算符,是运算符进入运算符栈,是操作数进入操作数栈,这里还要分别写进栈函数,后面再进栈,栈里面已经有数据了,所以这里还要判断运算符的优先级,是判断栈最上面那个运算符和要输入的运算符,如果栈里的运算符优先级高,拿就要将栈里的运算符出栈,操作数栈里也要依次从栈的最上面去两个操作数进行计算,计算完,需要将计算得出的结果再入操作数栈,为后面计算用,入栈后,还要比较要入栈的这个运算符和运算符栈里的最上面的运算符进行比较,如果比栈最上面的运算符优先级高就将其入栈,依次类推,这里到最后还会剩余一对式子要计算,所以在最后还要将其再分别取出来计算得出结果再如操作数栈,最后再去栈里将其取出,得出结果,文字叙述不太清楚,我把代码贴上,比较简陋,但能表示就是那回事儿。别嫌弃哈!

#include <stdio.h>
#include <stdlib.h>

enum ret{MALLOC_OK , MALLOC_NO , CREATE_OK , CREATE_NO};
#define SIZE 20

/*
 *计算 + - × / 的四则运算
 *
 * */

//定义结构体
struct stack1_node
{
    char data[SIZE];    //栈空间

    int top;           //相当于指针,栈里存了多少,进行标识
};


typedef struct stack1_node Stack;

typedef Stack * Hstack;

//创建结点
int create_node(Hstack *new_node)
{
    *new_node = (Hstack)malloc(sizeof(Stack));

    if(*new_node == NULL)
    {
        return MALLOC_NO;
    }

    return MALLOC_OK;
}

//创建栈
int create_stack(Hstack *head)
{
    if(MALLOC_OK == create_node(head))
    {
        return CREATE_OK;
    }

    return CREATE_NO;

}

//初始化栈
void init_stack(Hstack head)
{
    head->top = -1;
}

//判断栈是否为空
int is_empty(Hstack stack)
{
    if(stack->top == -1)
    {
        return 0;
    }

    return 0;
}


//操作数进栈
void push_stack_num(Hstack stack2, int op_num)
{
    stack2->data[++(stack2->top)] = op_num;

    printf("push_num   %d\n", stack2->data[stack2->top]);

}

//操作数出栈
int pop_stack_num(Hstack stack2)
{
    if(is_empty(stack2) == -1)
    {
        return -1;
    }

    int num = stack2->data[stack2->top];

    (stack2->top)--;

    return num;
}

//运算符进栈
void push_stack_ch(Hstack stack1, int op_ch)
{
    stack1->data[++(stack1->top)] = op_ch;

    printf("push_ch   %c\n", stack1->data[stack1->top]);

}

//运算符出栈
int pop_stack_ch(Hstack stack1)
{
    if(is_empty(stack1) == -1)
    {
        return -1;
    }

    char ch = stack1->data[stack1->top];

    (stack1->top)--;

    return ch;
}



//拿出运算符栈里的最上面的字符
int get_ch_top(Hstack stack1)
{
   if(is_empty(stack1) == -1)
   {
       return -1;
   }

   return stack1->data[stack1->top];
}

//判断两个字符串
int get_priority(char ch)
{
    if(ch == '-' || ch == '+')
    {
        return 1;
    }

    if(ch == '*' || ch == '/')
    {
        return 2;
    }
}

//比较运算符栈中最上面的运算符域输入的运算符哪一个优先级大
int compare_ch(char op_ch_out, char ch)
{
    if(get_priority(op_ch_out) >= get_priority(ch))
    {
        return 1;
    }

    return -1;
}

//计算
int count(int num1, int num2, char ch)
{
    int result;

    switch(ch)
    {
        case '+':{ 
                     result = num2 + num1;
                     break;
                 }

        case '-': {
                      result = num2 - num1;
                      break;
                  }

        case '*': {
                      result = num2 * num1;
                      break;
                  }

        case '/': {
                      result = num2 / num1;
                      break;
                  }
    }

    return result;

}

//输入数据
void get_input(Hstack stack1, Hstack stack2)
{
    int num1,num2;
    char ch;
    int op_num;
    int op_ch_out;
    int result;
    int op_num_input;
    
    printf("请输入运算式:\n");

    while((ch = getchar()) != '\n')    //这里可不可以直接换成getchar() != '\n'
    {
        if(ch >= '0' && ch <= '9')
        {
            //进入操作数栈
            op_num_input = ch - '0';   
            push_stack_num(stack2, op_num_input);  //操作数进栈

        }
        else
        {
            if( ch == '+' || ch == '-' || ch == '*' || ch == '/' )
            {
                do
                {
                    op_ch_out = get_ch_top(stack1);    //查看运算符栈空间里是否有字符

                    if(op_ch_out == -1)      //没有字符
                    {
                        push_stack_ch(stack1, ch);   //直接进栈
                    }
                    else 
                    {
                        if(compare_ch(op_ch_out, ch) < 0)   //如果有字符,将两个字符进行比较
                        {
                            push_stack_ch(stack1, ch);      //如果比栈里面的大,则进栈

                            break;
                        }
                        else
                        {
                            num1 = pop_stack_num(stack2);  //取出操作数栈中的数
                            num2 = pop_stack_num(stack2);
                            op_ch_out = pop_stack_ch(stack1);  //取出运算符栈中的最上面运算符

                            if( num1 == -1 || num2 == -1 || op_ch_out == -1)  //栈是空栈
                            {
                                printf("stack is empty!\n");
                            }

                            printf("%d , %d , %c\n", num1,num2,ch); 
                            printf("\n");

                            //计算
                            result = count(num1,num2,op_ch_out);

                            push_stack_num(stack2,result);    //将算出来的结果放到操作数栈,准备下次运算

                        }
                    }

                }while(compare_ch(op_ch_out, ch) > 0);
            }
        }
    }

    while(is_empty(stack1) != -1 && is_empty(stack2) != -1)
    {
        num1 = pop_stack_num(stack2);  //取出操作数栈中的数
        num2 = pop_stack_num(stack2);
        op_ch_out = pop_stack_ch(stack1);  //取出运算符栈中的最上面运算符

        result = count(num1, num2, op_ch_out);
        push_stack_num(stack2, result);
    }

    printf("%d , %d , %c\n",num1,num2,op_ch_out);

    printf("result is:  %d\n",result);
}

void test()
{
    //定义头指针
    Hstack head1 = NULL;  //运算符栈的头指针
    Hstack head2 = NULL;  //操作数的头指针

    //创建栈
    create_stack(&head1);   //运算符栈
    create_stack(&head2);   //操作数栈

    //初始化栈
    init_stack(head1);
    init_stack(head2);

    //接收字符
    get_input(head1,head2);

    free(head1);
    free(head2);
    
}

int main(int agrc, char **argv)
{
    test();
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值