题解 | #表达式求值#

表达式求值

http://www.nowcoder.com/practice/9566499a2e1546c0a257e885dfdbf30d

抄的大佬的答案。

总体思路就是将表达式化为若干项的和。

即将带正号的加数本身入栈。

将带负号的加数的相反数入栈。

将带乘号的元素与乘号后的元素求积后入栈。

将带乘号的元素与除号后的元素求商后入栈。

再将栈中所有的元素求和。

此中用数组模拟栈,缺点是要控制索引。

也可以用入栈出栈相关函数代替。

但是再调试时出现未知错误使元素无法写入栈中,故而用数组模拟。

值得关注的是初始计算操作的设定、负号的处理和括号的处理。

初始计算操作设为“加”。

因为第一个元素有可能是负数,故而在子函数开始的第一步就判断是否有负号。

如果有负号,则将操作负设置为“减”,后边将相反数入栈。

如果是乘号,只影响其后面的元素,让该元素与前面元素相乘。

括号的处理则是迭代一个函数,越过括号之后再进行一个新的循环,将括号里的内容计算完毕后将其最终值入栈,入栈的位置是stack[i],其中i为加号的个数。

迭代也在循环之中,因此与单片机中断十分相似。

在被迭代的函数中,虽然开辟了两个相同名称的储存空间,但不会占用同一块内存。所以无需担心数据被覆盖。

i是控制字符串的指针的重要标志,因此无论多少次迭代,i始终只能单向变化。

因此i赋初值只能在子函数之外,否则每迭代一次i都将从初值位置开始,会将指针指向错误的位置并使循环无法结束。

注意求每次子函数求和时的索引要另辟新变量,不要重复用指针的标志i,也会导致指针指向错误位置。


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

 int i=0;


int trans(char *s)//取加数
{  
    int stack[100];
    int len;
   
    
    int top=-1;
    char flag='+';
    int val;
    int asb;
    len=strlen(s);

    while(i<=len)  
    {
        int num=0;
        if(*(s+i)=='-')//第一位是负数的情况
        {
            flag='-';
            i++;
            
        }
        
        if(*(s+i)=='(')
        {
            i++;
            num=trans(s);
            
        }
        while((*(s+i)-'0'>=0)&&(*(s+i)-'0'<=9))
        {
            num=num*10+(*(s+i)-'0');//将字符型转换为整型,算超过一位的数字需要多次
            i++;
          //  count++;
        }
                                                                                                                                                                                                                                                                                                                                                                                                                       
        
        switch(flag)
        {
            case'+':
                {
                    stack[++top]=num;
                   // stack_push(stack,num);
                    break;
                }
            case'-':
                {
                    //stack_push(stack,(-1)*num);
                    stack[++top]=(-1)*num;
                    break;
                }
            case'*':
                {
                    // asb=stack_pop(stack);//第一步flag默认为‘+’,因此不必担心取空
                     //stack_push(stack,asb*num);     
                    stack[top] *= num; 
                     break;
                }
            case'/':
                {
                    //asb=stack_pop(stack);
                    //stack_push(stack,asb/num);  
                    stack[top] /= num;
                    break;
                }      
        }
            flag=*(s+i);//取下一个符号
        if (*(s+i) == ')')
        {
            i++;
            break;
        }
           i++;    
        
        
    }
    
    int sum=0;
    for(int j=0;j<=top;j++)
    {
        sum=sum+stack[j];
    }
    
    return sum; 
}




int main()
{
    int award;
    //int count=0;
    char *s;
    s=(int*)malloc(sizeof(int));
    scanf("%s\n",s);
    award=trans(s);
    printf("%d",award);
    
}


全部评论

相关推荐

牛客868257804号:九个中铁八个中建
点赞 评论 收藏
分享
勇敢的联想人前程似锦:如果我是你,身体素质好我会去参军,然后走士兵计划考研211只需要200多分。
点赞 评论 收藏
分享
1 2 评论
分享
牛客网
牛客企业服务