1. 程式人生 > >入坑codewars第18天-Alphabet wars - nuclear strike

入坑codewars第18天-Alphabet wars - nuclear strike

題目:Alphabet wars - nuclear strike

Introduction

There is a war and nobody knows - the alphabet war!
The letters hide in their nuclear shelters. The nuclear strikes hit the battlefield and killed a lot of them.

Task

Write a function that accepts battlefield string and returns letters that survived the nuclear strike.

  • The battlefield string consists of only small letters, #,[ and ].
  • The nuclear shelter is represented by square brackets []. The letters inside the square brackets represent letters inside the shelter.
  • The # means a place where nuclear strike hit the battlefield. If there is at least one #
     on the battlefield, all letters outside of shelter die. When there is no any # on the battlefield, all letters survive (but do not expect such scenario too often ;-P ).
  • The shelters have some durability. When 2 or more # hit close to the shelter, the shelter is destroyed and all letters inside evaporate. The 'close to the shelter' means on the ground between the shelter and the next shelter (or beginning/end of battlefield). The below samples make it clear for you.

Example

abde[fgh]ijk     => "abdefghijk"  (all letters survive because there is no # )
ab#de[fgh]ijk    => "fgh" (all letters outside die because there is a # )
ab#de[fgh]ij#k   => ""  (all letters dies, there are 2 # close to the shellter )
##abde[fgh]ijk   => ""  (all letters dies, there are 2 # close to the shellter )
##abde[fgh]ijk[mn]op => "mn" (letters from the second shelter survive, there is no # close)
#ab#de[fgh]ijk[mn]op => "mn" (letters from the second shelter survive, there is no # close)
#abde[fgh]i#jk[mn]op => "mn" (letters from the second shelter survive, there is only 1 # close)
[a]#[b]#[c]  => "ac"
[a]#b#[c][d] => "d"
[a][b][c]    => "abc"
##a[a]b[c]#  => "c"

題意:

題目意思就是:
[a]#[b]#[c]  => "ac"

#號代表炸彈,[]代表保護門,如果一對門[]附近的‘#’之和大於等於2,則這扇門就會被炸掉包括[]裡面的元素;
如果沒有就保留所有的元素;

思路:

思路就是:
考慮兩種情況:
1:沒有一個‘#’號
2:有‘#’號就計算‘[]’號兩邊的#號個數

程式碼如下:

 由於寫的過程不斷修改因此程式碼比較冗餘;不夠精簡

def alphabet_war(battlefield):
    string1=""
    list1=[]
    list2=[]
    string2=""
    string3=""
    a=0
    
    if battlefield.find('#') == -1:
        for x in battlefield:
            if x != '[' and x != ']':
                string3=string3+x
        return string3
    
    for i in range(0,len(battlefield)):
        if battlefield[i]=='[':
            list1.append(a)
            #print(1)
        if battlefield[i]=='#':
            a=a+1
            #print(2)
        if battlefield[i]==']':
            a=0
            #print(3)
        if i==len(battlefield)-1:
            list1.append(a)
        #print(list1)
    #------
    for i in range(0,len(battlefield)):
        if battlefield[i]=='[':
            for j in range(i+1,len(battlefield)):
                if battlefield[j]==']':
                    list2.append(string1)
                    string1=""
                    break
                else:
                    string1=string1+battlefield[j]
            #print(list2)        
    #---------
    j=0
    for i in range(0,len(list1)-1):
        c=list1[i]+list1[i+1]
        if c < 2:
            string2=string2+list2[j]
        j=j+1
    return string2

 看看大神的吧:

import re
def alphabet_war(b):
    if '#' not in b:
        return re.sub(r"[\[\]]","",b)
    p = re.compile('([a-z#]*)\[([a-z]+)\](?=([a-z#]*))')
    return  ''.join( e[1] if (e[0]+e[2]).count('#') < 2 else'' for e in p.findall(b))

大神用的正則表示式:原來正則表示式就是這麼用:re.sub(r"[\你想要去掉的字元]")

+ 代表至少一個

* 代表0-n個

?代表對?前面的RE進行0或1個重複

(?=...)代表 例如, Isaac(?=Asimov) 只有跟隨著'Asimov'才會匹配'Isaac'。

/(\w)((?=111)(1))+/.test("1111") // true
/(\w)((?=111)(1))+/.test("2222") // false
/(\w)(?=\1{3,})/.test("AAAAAAAA") //true
/(\w)(?=\1{3,})/.test("AAAB") //false

 

關於compile():

對於re.compile()則是用於編譯正則表示式,生成一個正則表示式( Pattern )物件,其他函式使用。

group([group1, …]) 方法用於獲得一個或多個分組匹配的字串,當要獲得整個匹配的子串時,可直接使用 group() 或 group(0);
start([group]) 方法用於獲取分組匹配的子串在整個字串中的起始位置(子串第一個字元的索引),引數預設值為 0;
end([group]) 方法用於獲取分組匹配的子串在整個字串中的結束位置(子串最後一個字元的索引+1),引數預設值為 0;
span([group]) 方法返回 (start(group), end(group))。
>>>import re
>>> pattern = re.compile(r'\d+')                    # 用於匹配至少一個數字
>>> m = pattern.match('one12twothree34four')        # 查詢頭部,沒有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 2, 10) # 從'e'的位置開始匹配,沒有匹配
>>> print m
None
>>> m = pattern.match('one12twothree34four', 3, 10) # 從'1'的位置開始匹配,正好匹配
>>> print m                                         # 返回一個 Match 物件
<_sre.SRE_Match object at 0x10a42aac0>
>>> m.group(0)   # 可省略 0
'12'
>>> m.start(0)   # 可省略 0
3
>>> m.end(0)     # 可省略 0
5
>>> m.span(0)    # 可省略 0
(3, 5)

關於findall() :

在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。

# -*- coding:UTF8 -*-
 
import re
 
pattern = re.compile(r'\d+')   # 查詢數字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
 
print(result1)
print(result2)

輸出: 

['123', '456']
['88', '12']