带括号的表达式计算(后缀表达式实现)

从标准输入中读入一个整数算术运算表达式,如24 / ( 1 + 2 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 )= ,计算表达式结果,并输出。

要求:

1、表达式运算符只有+、-、*、/,表达式末尾的=字符表示表达式输入结束,表达式中可能会出现空格;
2、表达式中会出现圆括号,括号可能嵌套,不会出现错误的表达式;

3、出现除号/时,以整数相除进行运算,结果仍为整数,例如:5/3结果应为1。

4、要求采用逆波兰表达式来实现表达式计算。

 

【输入形式】

从键盘输入一个以=结尾的整数算术运算表达式。操作符和操作数之间可以有空格分隔。

【输出形式】

在屏幕上输出计算结果(为整数,即在计算过程中除法为整除)。

【样例输入】

24 / ( 1 + 2 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 )     =

【样例输出】

18
【样例说明】

按照运算符及括号优先级依次计算表达式的值。

思路和方法在注释当中写有哦~

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>
int main()
{
    int top_post = -1,  top_stack = -1;  //top_post表示指向后缀表达式的 “指针”, top_stack 表示指向栈的 “指针” 
    char postfix[100] = "0"; //存放后缀表达式的数组,后面的cal_stack 才是真正用来运算的栈 
    char stack[100] = "0";  //存放运算符号的栈 
    int num_stack[100] = {0};
    
    char num[32] = {0} ;  /*temporarily store the char that is number and turn them into integer遇到是数字的字符后期转化为int型*/
    int m = 0, number = 0, k;
    char tmp;

    /*turn it into postfix expression*/
    while(1)
    {
    	scanf("%c", &tmp);
    	if(tmp == '=') break;   /*遇到等号则式子输入结束,退出循环*/
		else if( isdigit(tmp) ) /*如果发现tmp是数字,则往下get a complete integer读入完整整数*/
        {
        	m = 0;
        	while( isdigit(tmp) )
        	{
        		num[m++] = tmp;  /*从0开始存,然后在 + 1 ,存到下一个下标*/
        		scanf("%c", &tmp);
			}
        	
        	ungetc(tmp, stdin); //最后会多读一个不是digit的字符,退回 
        	
 			num[m] = '\0';
            number = atoi(num);     //会得到该完整整数的字符串
            
            postfix[++top_post] = 'n';     /*由于数字都混在一起难以分辨,这里用n 替代一个数字的位置,put sth as substitue of number*/
            num_stack[top_post] = number;  /*数字栈中的number 和postfix当中的n位置是一一对应的,number stack sync with postfix*/

            memset(num, 0, sizeof(num)); /*清空num 数组以便下一轮使用*/
        }

        else if( isspace(tmp) )  continue;

        else if( tmp == '*' || tmp == '/' )  /*若发现乘除运算,优先级别高,则先把所有紧随其后的乘除运算出栈弄掉,放到后缀表达式里*/
        {
        	while( stack[top_stack] == '*' || stack[top_stack] == '/' )
            {
                postfix[++top_post] = stack[top_stack];
                top_stack--;
            }
            stack[++top_stack] = tmp;
        }

        else if(tmp == '+' ||tmp == '-'  )
        {
            while( stack[top_stack] == '*' || stack[top_stack] == '/' )
            {
                postfix[++top_post] = stack[top_stack];
                top_stack--;
            }
            stack[++top_stack] = tmp;
        }

        else if(tmp=='(')
        {
            stack[++top_stack] = tmp;
        }

        else if(tmp == ')')
        {
            while( stack[top_stack] != '(' )   //遇到右括号,一直出栈至找到左括号 
            {
                postfix[++top_post] = stack[top_stack];
                top_stack--;
            }
            top_stack--; /*然后出栈删除掉左括号delete the left bracket*/
            stack[top_stack+1] = '\0';
        }

    }
    /*after read the equal '=' */
    while( top_stack > -1 )
    {
    	postfix[++top_post] = stack[top_stack];
    	top_stack--;
	}
    
    stack[++top_stack] = '\0';
    postfix[++top_post] = '\0';
	printf("%s\n", postfix);   //可以查看后缀表达式,其中的 n 就是对应的数字 

    /*now the top_stack should be -1;*/
    /*下面根据后缀表达式开始计算 calculate the postfix expression*/
    int cal_stack[100]; 
    int i = 0;
    int tmp_result;
    top_stack = -1;  //此处top_stack 是指向 cal_stack 顶部的 “指针” 
    while( postfix[i] != '\0' )
    {
        if( postfix[i] == 'n' )     /*it is supposed to be a number 发现 n 表明读到一个数字,让数字入栈*/
        {
        	cal_stack[++top_stack] = num_stack[i];    /*现在处于表达式的第 i 个位置,在运算栈中放入num_stack 对应位置的真实数字*/
        }

        else if( postfix[i] == '*' )  //让前一个数字和当前数字 对该符号进行运算 并加到结果里 
        {
            tmp_result = cal_stack[top_stack-1] * cal_stack[top_stack];
            top_stack = top_stack - 2;                       //两个已经参加运算的数字出栈 
            cal_stack[++top_stack] = tmp_result;             //用该运算结果替代刚才运算的元素,如此往复 
        }

        else if(postfix[i] == '/')
        {
            tmp_result = cal_stack[top_stack-1] / cal_stack[top_stack];
            top_stack = top_stack - 2;
            cal_stack[++top_stack] = tmp_result;
        }

        else if(postfix[i] == '+')
        {
            tmp_result = cal_stack[top_stack-1] + cal_stack[top_stack];
            top_stack = top_stack - 2;
            cal_stack[++top_stack] = tmp_result;
        }

        else if(postfix[i] == '-')
        {
            tmp_result = cal_stack[top_stack-1] - cal_stack[top_stack];
            top_stack = top_stack - 2;
            cal_stack[++top_stack] = tmp_result;
        }

        i++;
    }
	//最后可直接得到运算结果 
    printf("%d", tmp_result);
    return 0;
    
}

  • 1
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值