[Python3 練習] 010 找出藏在字符串中的「密碼」

題目:找出藏在字符串中的「密碼」

(1) 描述

1) 題源 1 <a href="http://www.pythonchallenge.com/" target="_blank">Python Challenge, level 3</a>

2) 題源 2 <a href="https://fishc.com.cn/thread-42685-1-1.html" target="_blank">小甲魚老師的 Python 課程,第 20 講課後習題</a>

3) 修改

  • 題中帶有一條極長的字符串,不方便寫在此隨筆中
  • 我本身心血來潮,將題目小小地改動了一下(實際上是下降了難度)
  • 具體見下方要求

(2) 要求

  • 有一字符串,僅含英文字母(沒有回車、空格)
  • 如有 1 個小寫的英文字母,其左右兩邊均有且僅有 3 個大寫字母,則將其挑出
  • 將全部挑出的字母按順序輸出
  • 例如
    • 字符串:AAAAjBBBpCCCrDDmEEEyFFFqqGGG
    • 輸出:py

(3) 程序

解法 1:一一檢測(像是暴力破解)

<br>html

def decrypt(string):
    len_str = len(string)
    target = 4
    
    if \	# 檢測開頭,即檢測整串字符串的第 3 位
    string[0].isupper() and \
    string[1].isupper() and \
    string[2].isupper() and \
    string[3].islower() and \
    string[4].isupper() and \
    string[5].isupper() and \
    string[6].isupper() and \
    string[7].islower():
        print(string[3], end='')
    
    while target < len_str-4:
        if \# 檢測中間
        string[target-4].islower() and \	# 如有多種字符,可用 not string[i].isupper()
        string[target-3].isupper() and \
        string[target-2].isupper() and \
        string[target-1].isupper() and \
        string[target  ].islower() and \
        string[target+1].isupper() and \
        string[target+2].isupper() and \
        string[target+3].isupper() and \
        string[target+4].islower():
            print(string[target], end='')
            target += 4
        else:
            target += 1
       
    if \	# 檢測結尾,即檢測整串字符串的倒數第 4 位
    string[len_str-7].islower() and \
    string[len_str-6].isupper() and \
    string[len_str-5].isupper() and \
    string[len_str-4].islower() and \
    string[len_str-3].islower() and \
    string[len_str-2].isupper() and \
    string[len_str-1].isupper() and \
    string[len_str  ].isupper():
        print(string[len_str-3], end='')

<br>python

解法 2:利用編號

  • 利用列表,使字符串中的每一個字符都有一個對應的編號
  • 由於字符串中只有大小寫英文字母,因此先理出全部小寫英文字母的編號,再檢查編號的間距
  • 若某個編號與其左右相鄰的編號均相差 4,則該編號對應的字母即爲所求之一
ABCdEFGhIj
0123456789
   ↓   ↓ ↓
   3   7 9 # 第一輪,篩出小寫字母的編號
   ↓
   3       # 第二輪,篩出符合規則的字母的編號

<br>app

def decrypt(string):
    len_str = len(string)
    list0 = []
    for i in range(len_str):			# 找出全部小寫字母在 string 中的編號,並寫入 list0
        if string[i].islower():
            list0.append(i)

    list1 = []
    if list0[0] == 3 and list0[1] == 7:	# 檢測開頭,即檢測整串字符串的第 3 位
        list1.append(3)
    for i in range(1, len(list0)):		# 檢測中間,找出 list0 中符合要求的小寫字母的編號
        if (list0[i]-4) == list0[i-1] and (list0[i]+4) == list0[i+1]:
            list1.append(list0[i])
    if list0[-1] == len_str-4 and list0[-2] == len_str-8:
    # 檢測結尾,即檢測整串字符串的倒數第 4 位
        list1.append(list0[-1])

    for i in list1:						# 輸出
        print(string[i], end='')

<br>spa

解法 3:利用 3 個變量,統計大小寫字母的個數

(詳見下方 countA、countB、countC)code

def decrypt(string):    
    countA = 0  # 統計小寫字母左側的大寫字母
    countB = 0  # 統計小寫字母
    countC = 0  # 統計小寫字母右側的大寫字母

    len_str = len(string)
    for i in range(len_str):
        if string[i].isupper():
            if countB:				# AAAaA; AAAaAA; AAAaAAA
                countC += 1
            else:					# A; AA; AAA; AAAA ...
                countC = 0
                countA += 1

        if string[i].islower():
            if countA != 3:			# a; Aa; AAa; AAAAa ... 
                countA = 0
                countB = 0
                countC = 0
            else:
                if countB:			# AAAaa
                    countA = 0
                    countB = 0
                    countC = 0
                else:				# AAAa
                    countB = 1
                    countC = 0
                    target = i

        if countC == 3:
            if i+1 != len_str and \	# 若 i 未迭代到最後一位
            string[i+1].isupper():	# AAAaAAAA
                countB = 0
                countC = 0
            else:					# AAAaAAAb 總算找到了一個 a
                print(string[target], end='')
                countA = 3			# AAAb
                countB = 0
                countC = 0

<br>htm

解法 4:re 模塊

  • re 模塊像「掛」似的
import re

text = "xxx"									# 改 x 或用文件導入
pattern = "[^A-Z][A-Z]{3}([a-z])[A-Z]{3}[^A-Z]"	# 設置格式
print(''.join(re.findall(pattern, text)))
相關文章
相關標籤/搜索