思路:遇到非操作符(即+_*/()#)就输出,否则判断优先级,若优先级大则入栈,优先级小则将栈顶元素输出。
另外需要注意括号,括号不能输出,而且会被当做优先级很高的操作符以达到判断到')'时可以将'('右边的元素都输出。
由于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