为了OFFER | 腾讯2020校招后端《解压字符串》

@Author:Runsen
@Date:2020/9/6

大四刷题拼offer系列,不拼不行啊。自己知道自己的数据结构算法很菜。而且2020/9/6今晚还有腾讯的笔试,祝我好运吧。自己知道成功的可能性很低,但还是刷下腾讯的算法题。

题目

题目:小Q想要给他的朋友发送一个神秘字符串,但是他发现字符串的过于长了,于是小Q发明了一种压缩算法对字符串中重复的部分进行了压缩,对于字符串中连续的m个相同字符串S将会压缩为[m|S](m为一个整数且1<=m<=100),例如字符串ABCABCABC将会被压缩为[3|ABC],现在小Q的同学收到了小Q发送过来的字符串,你能帮助他进行解压缩么?

'''
@Author: Runsen
@WeChat:RunsenLiu 
@微信公众号: Python之王
@CSDN: https://blog.csdn.net/weixin_44510615
@Github: https://github.com/MaoliRUNsen
@Date: 2020/9/6

输出一个字符串,代表解压后的字符串。

输入例子1:
HG[3|B[2|CA]]F

输出例子1:
HGBCACABCACABCACAF

例子说明1:
HG[3|B[2|CA]]F−>HG[3|BCACA]F−>HGBCACABCACABCACAF
'''

这道题看似很简单,自己看着明白,脑子想明白了,但是就是敲不出,每次运行就是还有一个数据不合适,可能是内存的原因。其实关键就是如何找到[,|,]的index。

第一种思路

我相信很多人都是和我一样,直接找到直接遍历,如果遇到了第一个],就往会回遍历寻找[,|。这里遍历如果写for循环就觉得很难读懂,下面的代码j就是[的index,k就是|的index,i就是]的index。然后就是用replace,记作字符串是不可变类型,只能用replace,还有一种方法就是新建一个字符串,但是空间内存变大了。

if __name__=='__main__':
    s=input()
    i=0
    while(i<len(s)):
        if(s[i]==']'):
            j=i
            k=0
            while(s[j]!='['):
                if(s[j]=='|'):
                    k=j
                j=j-1
            s1=s[j:i+1]
            num=int(s[j+1:k])
            sz=s[k+1:i]
            sz=sz*num
            s=s.replace(s1,sz,1)
            i=j
        i = i + 1
    print(s)

第二种思路

第二种思路还是遍历,但是想法和上面的不相同,就是找到]的index,就是break,同时储存前面的[的index,和|的index,这样就不断地进行递归解码,直到一个中括号都没有。

def decode(s):
    i = 0
    x, y, z = -1, -1, -1
    while i < len(s):
        if s[i] == '[':
            x = i
        elif s[i] == '|':
            y = i
        elif s[i] == ']':
            z = i
            break
        i += 1
    if x != -1 and y != -1 and z != -1:
        times = int(s[x + 1:y])  # 次数
        sub = s[y + 1:z]  # 子串
        decode_str = s[:x] + times * sub + s[z + 1:]  # 解码
        return decode(decode_str)  # 递归解码
    return s  # 如果一个中括号都没有,说明没有需要解码的部分


if __name__ == '__main__':
    s = input()
    print(decode(s))

第三种思路

第三种思路就是使用正则,我是看别人都代码才知道的思路,通配符写成r"\[(\d+)\|(\w+)\]"这里的\表示转义的意思。search返回的结果是竟然可以通过span取值,这个是我学正则不知道的!!!!!!

import re

line = input()
pattern = r"\[(\d+)\|(\w+)\]"
tmp = re.search(pattern, line)
print(tmp)
while tmp:
    l, r = tmp.span()[0], tmp.span()[1]
    cur = line[l:r]
    mid = cur.find("|")
    num = int(cur[1:mid])
    chs = cur[mid + 1:-1] * num
    line = line[:l] + chs + line[r:]
    tmp = re.search(pattern, line)
    print(tmp)
print(line)


HG[3|B[2|CA]]F
<re.Match object; span=(6, 12), match='[2|CA]'>
<re.Match object; span=(2, 11), match='[3|BCACA]'>
None
HGBCACABCACABCACAF

看了腾讯第一道的解压字符串,就知道自己有多垃圾了。正因为自己垃圾,才需要不断地提高字自己的水平。

如果你想跟博主建立亲密关系,可以关注博主,或者关注博主公众号“Python之王”,了解一个非本科程序员是如何成长的。
博主ID:润森(weixin_44510615),希望大家点赞、评论、收藏

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小刘要努力。

顺便点一个赞

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值