1. 程式人生 > >1003 我要通過 python實現

1003 我要通過 python實現

1003 我要通過!(20)(20 分)

答案正確”是自動判題系統給出的最令人歡喜的回覆。本題屬於PAT的“答案正確”大派送 —— 只要讀入的字串滿足下列條件,系統就輸出“答案正確”,否則輸出“答案錯誤”。

得到“答案正確”的條件是:

1. 字串中必須僅有P, A, T這三種字元,不可以包含其它字元;\

  1. 任意形如 xPATx 的字串都可以獲得“答案正確”,其中 x 或者是空字串,或者是僅由字母 A 組成的字串;\
  2. 如果 aPbTc 是正確的,那麼 aPbATca 也是正確的,其中 a, b, c 均或者是空字串,或者是僅由字母 A 組成的字串。

現在就請你為PAT寫一個自動裁判程式,判定哪些字串是可以獲得“答案正確

”的。

輸入格式: 每個測試輸入包含1個測試用例。第1行給出一個自然數n (&lt10),是需要檢測的字串個數。接下來每個字串佔一行,字串長度不超過100,且不包含空格。

輸出格式:每個字串的檢測結果佔一行,如果該字串可以獲得“答案正確”,則輸出YES,否則輸出NO。

輸入樣例:

8
PAT
PAAT
AAPATAA
AAPAATAAAA
xPATx
PT
Whatever
APAAATAA

輸出樣例:

YES
YES
YES
YES
NO
NO
NO
NO

下面我們分析一下該問題(只需要程式碼的同學可以直接看最後程式碼部分):

這是一道典型的字串匹配問題,是十分簡單的,但是問題的描述讓人有點搞不清楚題意,我在看滿分答案之前也沒有完全理解該題的意思。

第一個條件 :

1:任意形如xPATx的字串都可以獲得“答案正確”,其中x或者是空字串,或者是僅由字元A組成的字串

原字串中包含'PAT'這個子字串。且其餘字元全是字元'A'

第二個條件:

2:如果aPbTc是正確的,那麼aPbATca也是正確的,其中a,b,c均或者是空字串,或者是僅由字母A組成的字串。

我們是不是可以理解為,有形如'APATA'的字串,它是正確的,且在中間,和末尾各加一個字元'A'也是“正確答案”,顯然這樣理解是正確的。那麼加多個字元'A'是不是也正確呢?從實驗用例來看AAPAATAAAA是正確答案,我們可能會認為是不是在PAT的任意位置加任意個數的字元'A'都是正確的呢?從最後一個實驗用例來看顯然是錯誤的。

從其他滿分答案來看,有以下約束:

有形如xPyTx的字串,x是空字串,或者是僅由字元A組成的字串,y是僅由字元A組成的字串,我們以字元P,T進行分段,P前段為a,P T之間為b,T之後為c,則若它是正確答案,有c=a*len(b)

下面我們來看兩個實驗用例:

①字串AAPAATAAAA

a段:AA    b段:AA    c段:AAAA

有 AAAA=AA*len(AA)

    AAAA=AA*2

所以是正確答案

②字串APAAATAA

a段:A    b段:AAA    c段:AA

有AA=A*len(AAA)

等式不成立

所以是錯誤答案

理解了以上條件後,就可以很好地解決這道題了,演算法的基本思想就是,以P T為界分為三段來做條件判斷。

一:使用簡單的迴圈和條件語句實現

def test(a):
    x = -1
    y = -1
    for i in range(len(a)):#找出P,T的位置
        if (a[i]=='P'):
            x = i
        if (a[i]=='T'):
            y = i
    if (x==-1 or y==-1):#如果找不到P,T則返回0
        return 0
    if (x>y):#P在T的後面,返回0
        return 0
    if (y==x+1):#P,T之間沒有字元,返回0
        return 0
    if (x!=0):#字串不以P開頭
        b = a[0:x]
    else:#字串以P開頭
        b = []
    c = a[x+1:y]
    if (y!=len(a)-1):#字串不以T結尾
        d = a[y+1:len(a)]
    else:#字串以T結尾
        d = []
    for i in b:#判斷各個分段是否是字元A組成
        if (i!='A'):
            return 0
    for i in c:
        if (i!='A'):
            return 0
    for i in d:
        if (i!='A'):
            return 0
    if (d==b*len(c)):#條件判斷
        return 1
    else:
        return 0

n = input()
for i in range(int(n)):
    s = input()
    if (test(s)==1):
        print('YES')
    else:
        print('NO')

除了上述方法外,我們還可以使用正則表示式來對字串進行匹配

下面我們簡單介紹一下正則表示式,和使用到的幾個操作符

正則表示式是對字串的一種邏輯公式,就是實現定義好一些特定的字元,及這些特定字元的組合,組成一個“規則字串”,這個“規則字串”用來表達對字串的一種過濾邏輯。通常用來檢索,替換那些符合摸個模式的文字,常用於字串操作。

.

表示任何單個字元
[ ]字符集,對單個字元給出取值範圍[abc]表示a,b,c   [a-z]表示a到z的所有單個字元
[^]非字符集,對單個字元給出排除範圍[^abc]表示非a或b或c的單個字元
*前一個字元的零次或無限次擴充套件abc*表示ab,abc,abcc,abccc等
+前一個字元的一次或無限次擴充套件abc+表示abc,abcc,abccc等
前一個字元零次或一次擴充套件abc?表示ab,abc
|左右表示式任意一個abc|def表示abc,def
{m}擴充套件前一個字元m次ab{2}c表示abbc
{m,n}擴充套件前一個字元m至n次(含n次)ab{1,2}表示abc,abbc
^匹配字串開頭^abc表示abc且在一個字串的開頭
$匹配字串結尾abc$表示abc且在一個字串的結尾
()分組標記,內部只能使用|操作符(abc)表示abc,(abc|def)表示abc,def
\d數字,等價於[0-9]

綜上所述,問題中的字串用正則表示式表示為:A*PA+TA*

二:正則表示式求解

import re  
n=input()  
for i in range(int(n)):  
    s=input()  
    if re.match(r'A*PA+TA*',s): #在字串中進行匹配 
        a=re.split(r'[P|T]',s)  #以字元P,T進行分段
        if a[0]*len(a[1])==a[2]:  #條件判斷
            print('YES')  
        else:  
            print('NO')  
    else:  
        print('NO')