NYOJ 467

 

中缀式变后缀式

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
 
描述
人们的日常习惯是把算术表达式写成中缀式,但对于机器来说更“习惯于”后缀式,关于算术表达式的中缀式和后缀式的论述一般的数据结构书都有相关内容可供参看,这里不再赘述,现在你的任务是将中缀式变为后缀式。
 
输入
第一行输入一个整数n,共有n组测试数据(n<10)。
每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式的中缀式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
数据保证除数不会为0
输出
每组都输出该组中缀式相应的后缀式,要求相邻的操作数操作符用空格隔开。
样例输入
2

1.000+2/4=

((1+2)*5+1)/4=
样例输出
1.000 2 4 / + =

1 2 + 5 * 1 + 4 / =
/*

一、算法思想

声明一个数组S2用于存放结果。从左至右逐字读取数组S1,每次一个字符。根据当前字符的内容,进行如下操作:

1、当前字符为操作对象(数字或字母),直接输出到S2

2、当前字符为'(',将其压栈

3、当前字符为')',则弹出堆栈中最上的'('之前的所有运算符并输出到S2,然后从删除堆栈中最上的'('

4、当前字符为运算符,则依次弹出堆栈中优先级大于或等于当前运算符的优先级的运算符,再将当前运算符压栈

5、如果到达输入字符串S1的末尾,则弹出堆栈中剩下的所有运算符。

*/ 

#include <cstdio>

#include <cstring>

#include <stack>

#include <cctype>

#include <cstdlib>

using namespace std;

char str[1005];

/*

bool pri(char a,char b)

{

    if((a=='+'||a=='-')&&(b=='*'||b=='/'))

        return false;

    return true;

}

*/

const char ch[6][6]=

{ 

    {'>','>','<','<','<','>'},//栈顶和新输入的比较 

    {'>','>','<','<','<','>'},

    {'>','>','>','>','<','>'},

    {'>','>','>','>','<','>'},

    {'<','<','<','<','<','='},

    {'>','>','>','>',' ','>'}

};

int sign(char ch)

{

	switch(ch)

	{

		case '+' : return 0;

		case '-'  : return 1;

		case '*'  : return 2;

		case '/'  : return 3;

		case '('  : return 4;

		case ')'  : return 5;

		//default : exit(-1);

	}

}

bool pri(char a, char b)

{

	if(ch[sign(a)][sign(b)]=='>'||ch[sign(a)][sign(b)]=='=')

        return true;

    return false;

}

int main()

{

    int i,j,k,T;

    scanf("%d%*c",&T);

    while(T--)

    {

        stack <char> s;

        memset(str,0,sizeof(str));

        gets(str);

        int len = strlen(str);

        s.push(str[len-1]);//等号入栈 

        for(i=0;i<len-1;i++)

        {

            if(isdigit(str[i]))

            {

                //int pos1=strchr(str,'.')-str;

                /*

                使用strchr时,先定义一个字符型指针ptr, 

                if(ptr)(即存在)才 int pos1=strchr(str,'.')-str;

                否则,不可使用

                */ 

                j=i+1;

                while(isdigit(str[j])||str[j]=='.')

                    j++;

                for(k=i;k<=j-1;k++)

                    printf("%c",str[k]);

                putchar(' ');

                i=j-1;//不是 i=j,因为i还要自增 

            }                          

            else if(str[i]=='(')

                s.push(str[i]);                

            else if(str[i]=='+'||str[i]=='-'||str[i]=='*'||str[i]=='/')

            {    

                if(s.empty())

                    s.push(str[i]);                        

                while(pri(s.top(),str[i])&&s.size()!=1)//不处理最后的等号 

                {

                    printf("%c ",s.top());

                    s.pop();

                }

                s.push(str[i]);                                      

            }

            else if(str[i]==')')

            {

                while(s.top()!='('&&s.size()!=1)                

                {

                    printf("%c ",s.top());

                    s.pop();

                }

                s.pop();//去掉左括号 

            }

        }

         while(!s.empty()&&s.size()!=1)

         {

            printf("%c ",s.top());

            s.pop();  

         }

        printf("=\n"); 

        //system("pause");              

    }

        return 0;

}

 

你可能感兴趣的:(OJ)