swust oj 1042 _ 中缀表达式转换为后缀表达式(只要求输出)

思路:遇到非操作符(即+_*/()#)就输出,否则判断优先级,若优先级大则入栈,优先级小则将栈顶元素输出。

另外需要注意括号,括号不能输出,而且会被当做优先级很高的操作符以达到判断到')'时可以将'('右边的元素都输出。

由于1042的题目中将这种优先级的大小关系用proceed数组存下来,所以可以直接用。

#include
#include//1042
#include
#include
#define Maxsize 500
struct Stack
{
    char data[Maxsize];
    int top;
}*s;
 
//运算符优先级关系表
char proceed[7][7]=
{
    {'>','>','<','<','<','>','>'},
    {'>','>','<','<','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'>','>','>','>','<','>','>'},
    {'<','<','<','<','<','=','N'},
    {'>','>','>','>','N','>','>'},
    {'<','<','<','<','<','N','='}
};
 
int locate(char op) //把运算符op转换为优先级关系表中的序号
{
    switch(op)
    {
    case '+': return 0;
    case '-': return 1;
    case '*': return 2;
    case '/': return 3;
    case '(': return 4;
    case ')': return 5;
    case '#': return 6;
    }
    return -1;
} 
 
int xIsOperator(char x) //判别字符x是否为操作符
{
    char ops[]="+-*/()#";
    for(int i=0; i<7; ++i) //因为串ops的长度为7
        if(x==ops[i])
            return 1; //只要发现x是操作符,则返回true
    return 0;
} 
 
void Change(char ch[])
{
    s = (Stack *)malloc(sizeof(Stack));
    s->data[0] = '#';
    s->top = 0;
    int len;
    len = strlen(ch);
    ch[len] = '#';
    for(int i = 0; i <= len; i++)
    {
        if(xIsOperator(ch[i]) == 0)printf("%c",ch[i]);
        else 
        {
            switch(proceed[locate(s->data[s->top])][locate(ch[i])])
            {
            case '<':s->data[++s->top] = ch[i];break;
            case '>':printf("%c",s->data[s->top--]);i--;break;
            case '=':s->top--;break;
            case 'N':printf("输入错误");
            }
        }
    }
}
/*Change函数改了很多次,因为超时,首先从结构入手,由于一个字符如果优先级比较
高的话,可能会让栈顶多次输出,于是我想到了do……while语句,然而这样十分费时,毕竟是循环了。
而代码第64行的“i--”,极其巧妙地避免了循环并达到了循环的目的*/ 

/*然后对Change函数的修改重点放在case语句里(毕竟这个函数除了赋值也就这么点东西了),
最开始的入栈函数是:
void Insert(Stack *&s,char ch)
{
    s->top++;
    s->data[s->top] = ch;
}其实只有两句,可以合并成s->data[s->top++] = ch;只剩一句也可以不放在函数里了

最开始的出栈函数是:
void Pop(Stack *&s)
{
    char ch = s->data[s->top];
    if(ch == '+' || ch == '-' || ch == '*' || ch == '/')
    {
        printf("%c",s->data[s->top]);
        s->top--;
    }
}

然而在利用proceed函数比较时就排除了')'将'('输出的情况,它直接跳过了。于是代码删去冗杂

的判断之后就只剩两句,同上,合并。

*/ int main() { char ch[Maxsize]; scanf("%s",ch); Change(ch); return 0; }


另外,函数中出现了[++s->top]与[s->top--],主要还是看个人爱好,如果喜欢用栈的data[s->top]装栈顶数据的,就可以像我这样用。

如果喜欢用top表示data数组里数据的个数的,那么栈顶元素在data[s->top-1]里,就用[s->top++]与[--s->top],另外在初始化时也有点点区别。

原文出自:http://blog.csdn.net/qq_33810513/article/details/51288445




你可能感兴趣的:(swust,oj水题)