1. 程式人生 > >swust oj 1042 _ 中綴表示式轉換為字尾表示式(只要求輸出)

swust oj 1042 _ 中綴表示式轉換為字尾表示式(只要求輸出)

思路:遇到非操作符(即+_*/()#)就輸出,否則判斷優先順序,若優先順序大則入棧,優先順序小則將棧頂元素輸出。

另外需要注意括號,括號不能輸出,而且會被當做優先順序很高的操作符以達到判斷到')'時可以將'('右邊的元素都輸出。

由於1042的題目中將這種優先順序的大小關係用proceed陣列存下來,所以可以直接用。

#include<iostream>
#include<stdio.h>//1042
#include<string.h>
#include<malloc.h>
#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--;
    }
}<p>然而在利用proceed函式比較時就排除了')'將'('輸出的情況,它直接跳過了。於是程式碼刪去冗雜</p><p>的判斷之後就只剩兩句,同上,合併。</p>*/


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