[Python3 练习] 010 找出藏在字符串中的“密码”

题目:找出藏在字符串中的“密码”

(1) 描述

1) 题源 1 Python Challenge, level 3

2) 题源 2 小甲鱼老师的 Python 课程,第 20 讲课后习题

3) 修改

  • 题中带有一条极长的字符串,不方便写在此随笔中
  • 我自己心血来潮,将题目小小地改动了一下(其实是降低了难度)
  • 具体见下方要求

(2) 要求

  • 有一字符串,仅含英文字母(没有回车、空格)
  • 若有 1 个小写的英文字母,其左右两边均有且仅有 3 个大写字母,则将其挑出
  • 将所有挑出的字母按顺序输出
  • 例如
    • 字符串:AAAAjBBBpCCCrDDmEEEyFFFqqGGG
    • 输出:py

(3) 程序

解法 1:一一检测(像是暴力破解)

1576387-20190519220253707-791406518.png


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='')


解法 2:利用编号

  • 利用列表,使字符串中的每个字符都有一个对应的编号
  • 因为字符串中只有大小写英文字母,所以先理出所有小写英文字母的编号,再检查编号的间距
  • 若某个编号与其左右相邻的编号均相差 4,则该编号对应的字母即为所求之一
ABCdEFGhIj
0123456789
   ↓   ↓ ↓
   3   7 9 # 第一轮,筛出小写字母的编号
   ↓
   3       # 第二轮,筛出符合规则的字母的编号


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='')


解法 3:利用 3 个变量,统计大小写字母的个数

(详见下方 countA、countB、countC)

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


解法 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)))

转载于:https://www.cnblogs.com/yorkyu/p/10386418.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值