1. 程式人生 > >資料結構——表示式轉換

資料結構——表示式轉換

除去表示式轉換的基本規則,個人認為表示式轉換有以下三個難點:
1、小數沒有辦法表示和輸出;
2、數字本身自帶的負號難以表達和實現;
3、多位數字沒有辦法很好的去表達。

類如PTA 7-1這道題:

輸入格式:

輸入在一行中給出不含空格的中綴表示式,可包含+、-、*、\以及左右括號(),表示式不超過20個字元。

輸出格式:

在一行中輸出轉換後的字尾表示式,要求不同物件(運算數、運算子號)之間以空格分隔,但結尾不得有多餘空格。

輸入樣例:

2+3*(7-4)+8/4
輸出樣例:

2 3 7 4 - * + 8 4 / +

很多人(包括我自己,咳咳)在掌握了基本的轉換規則後,仍然無法解決此題,很多問題就是出現在上面提到的三點,可以拿著三點出幾組資料看看是否能卡死自己的程式碼。

在網上翻閱了很多的此類題的模板,在參考了這篇部落格後表示式轉換模板,精煉出了一套模板,在這裡與大家分享.

AC程式碼(此程式碼通過了PTA的測試資料),程式碼有點長,希望大家耐心看完:

#include <bits/stdc++.h>

using namespace std;
const int maxn=100;

char s[maxn];
int len;

bool judge(char c)
{
    return c=='-'||c=='+';
}

bool judge1(char c)
{
    return c=='(';
}

bool compare(char a,char b)//優先順序的比較
{
    if(a=='(') return 0;
    if(b=='+'||b=='-') return 1;
    else
    {
        if(a=='*'||a=='/') return 1;
        else return 0;
    }
}

void solve()
{
    char mark[maxn];
    int pos=0,flag=0;//flag用來控制中間空格的輸出,主要是多位數字的輸出

    for(int i=0;i<len;i++)
    {
        if((s[i]>='0'&&s[i]<='9')||s[i]=='.')//若為數字直接輸出,注意小數點的處理
        {
            if(flag)  printf(" ");
            printf("%c",s[i]);

            flag=0;
        }
        else if(judge(s[i])&&(i ? judge1(s[i-1]) : 1 ))//判斷負號是否為本身所有
        {
            if(s[i]=='-')
            {
                if(flag)  printf(" ");
                printf("%c",s[i]);

                flag=0;
            }
        }
        else//其餘字元的按規則處理
        {
            if(pos)
            {
                if(s[i]=='(') mark[pos++]=s[i];
                else if(s[i]==')')//對於左括號的處理
                {
                    while(pos--)
                    {
                        if(mark[pos]=='(') break;
                        printf(" %c",mark[pos]);
                    }
                }
                else
                {
                    while(pos)//對於優先順序規則的處理
                    {
                        if(compare(mark[pos-1],s[i]))  printf(" %c",mark[--pos]);//輸出符號前必然有數字的輸出,所以直接輸出空格即可
                   
                        else break;
                    }
                    mark[pos++]=s[i];
                }

            }
            else mark[pos++]=s[i];//如果為空則直接壓入

            for(int j=0;j<pos;j++)//判斷是否控制格式,主要是排除(、)對格式控制的影響
            {
                if(mark[j]!='(')
                {
                    flag=1;
                    break;
                }
            }
        }
    }
    while(pos)
    {
        printf(" %c",mark[--pos]);
    }

}

int main()
{
    scanf("%s",s);

    len=strlen(s);

    solve();

    return 0;
}