CSDN每日一题学习训练——Python版(新浪微博热门话题、Z 字形变换)

版本说明

当前版本号[20231117]。

版本 修改说明
20231117 初版

目录

文章目录

  • 版本说明
  • 目录
  • 新浪微博热门话题
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码
  • Z 字形变换
    • 题目
    • 解题思路
    • 代码思路
    • 参考代码

新浪微博热门话题

题目

​ 新浪微博可以在发言中嵌入“话题”,即将发言中的话题文字写在一对“#”之间,就可以生成话题链接,点击链接可以看到有多少人在跟自己讨论相同或者相似的话题。新浪微博还会随时更新热门话题列表,并将最热门的话题放在醒目的位置推荐大家关注。 本题目要求实现一个简化的热门话题推荐功能,从大量英文(因为中文分词处理比较麻烦)微博中解析出话题,找出被最多条微博提到的话题。 输入格式: 输入说明:输入首先给出一个正整数N(≤105),随后N行,每行给出一条英文微博,其长度不超过140个字符。任何包含在一对最近的#中的内容均被认为是一个话题,输入保证#成对出现。 输出格式: 第一行输出被最多条微博提到的话题,第二行输出其被提到的微博条数。如果这样的话题不唯一,则输出按字母序最小的话题,并在第三行输出And k more …,其中k是另外几条热门话题的条数。输入保证至少存在一条话题。 注意:两条话题被认为是相同的,如果在去掉所有非英文字母和数字的符号、并忽略大小写区别后,它们是相同的字符串;同时它们有完全相同的分词。输出时除首字母大写外,只保留小写英文字母和数字,并用一个空格分隔原文中的单词。 输入样例: 4 This is a #test of topic#. Another #Test of topic.# This is a #Hot# #Hot# topic Another #hot!# #Hot# topic 输出样例: Hot 2 And 1 more

解题思路

  1. 导入正则表达式模块re。
  2. 输入微博数量a,要求为小于等于105的正整数。
  3. 定义两个空列表b和c,分别用于存储微博内容和微博中的标签。
  4. 使用while循环,当微博数量小于输入的数量时,继续循环。
  5. 在循环中,输入微博内容x,要求小于140字。
  6. 如果微博内容长度小于140字,将微博内容添加到列表b中;否则提示用户重新输入。
  7. 使用正则表达式提取微博中的标签,并添加到列表c中。
  8. 计算每个标签在微博中出现的次数,并将结果存储在字典列表d中。
  9. 根据标签出现的次数对字典列表d进行降序排序。
  10. 输出出现次数最多的标签名称(首字母大写)和该标签在微博中出现的次数。

代码思路

  1. 导入正则表达式模块;

    import re  # 导入正则表达式模块
    
  2. 输入微博数量,要求为小于等于105的正整数;

    a = int(input('输入微博数量(小于等于105的正整数):'))  # 输入微博数量,要求为小于等于105的正整数
    
  3. 定义两个空列表,用于存储微博内容和标签;

    b = []  # 定义一个空列表,用于存储微博内容
    c = []  # 定义一个空列表,用于存储微博中的标签
    
  4. 使用while循环,当微博数量小于输入的数量时,继续循环;

    while len(b) < a:  # 当微博数量小于输入的数量时,继续循环
        x = input('请输入微博内容,小于140字:')  # 输入微博内容,要求小于140字
    
  5. 在循环中,输入微博内容,要求小于140字;

    if len(x) < 140:  # 如果微博内容长度小于140字
    
  6. 如果微博内容长度小于140字,将微博内容添加到列表b中;

    b.append(x)  # 将微博内容添加到列表b中
    
  7. 如果微博内容长度大于等于140字,提示用户重新输入;

       else:  # 如果微博内容长度大于等于140字
            print('信息超出140字限制,请从新输入。')  # 提示用户重新输入
    
  8. 使用正则表达式提取微博中的标签,并添加到列表c中;

    c += re.findall('#[^#]+#', x)  # 使用正则表达式提取微博中的标签,并添加到列表c中
    
  9. 计算每个标签在微博中出现的次数,并将结果存储在字典列表d中;

    d = [{'n': n, 'c': len(c) - len(re.findall('#[^#]+#', re.sub(n, '', ''.join(c.copy()))))} for n in set(c)]  # 计算每个标签在微博中出现的次数,并将结果存储在字典列表d中
    
  10. 根据标签出现的次数对字典列表d进行降序排序;

    e = sorted(d, key=lambda x: x['c'], reverse=True)  # 根据标签出现的次数对字典列表d进行降序排序
    
  11. 输出出现次数最多的标签名称,首字母大写;

    print(e[0]['n'].title())  # 输出出现次数最多的标签名称,首字母大写
    
  12. 输出该标签在微博中出现的次数。

print(e[0]['c'])  # 输出该标签在微博中出现的次数

参考代码

import re
a = int(input('输入微博数量(小于等于105的正整数):'))
b = []
c = []
while len(b)<a:
    x = input('请输入微博内容,小于140字:')
    if len(x)<140:
        b.append(x)
    else:
        print('信息超出140字限制,请从新输入。')
    c += re.findall('#[^#]+#',x)
d = [{'n':n,'c':len(c)-len(re.findall('#[^#]+#',re.sub(n,'',''.join(c.copy()))))} for n in set(c)]
e = sorted(d,key=lambda x:x['c'],reverse=True)
print(e[0]['n'].title())
print(e[0]['c'])

Z 字形变换

题目

将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

比如输入字符串为 “PAYPALISHIRING” 行数为 3 时,排列如下:

P A H N
A P L S I I G
Y I R

之后,你的输出需要从左往右逐行读取,产生出一个新的字符串,比如:“PAHNAPLSIIGYIR”。

请你实现这个将字符串进行指定行数变换的函数:

string convert(string s, int numRows);

示例 1:

输入:s = “PAYPALISHIRING”, numRows = 3
输出:“PAHNAPLSIIGYIR”

示例 2:

输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I

示例 3:

输入:s = “A”, numRows = 1
输出:“A”

提示:

1 <= s.length <= 1000
s 由英文字母(小写和大写)、‘,’ 和 ‘.’ 组成
1 <= numRows <= 1000

解题思路

  1. 首先计算字符串的长度n和行数N。
  2. 如果字符串长度为1或行数为1,直接返回原字符串。
  3. 计算中间行的间隔数S和每行的总字符数C。
  4. 计算完整循环的次数R和剩余的字符数RS。
  5. 计算每行剩余的字符数CE和最后一行剩余的字符数RR。
  6. 计算最后一行的字符数RX。
  7. 初始化一个空列表output,用于存储转换后的字符。
  8. 使用两层循环遍历每一行和每一列,根据当前字符所在的行数和位置计算出其在原字符串中的偏移量offset,然后根据偏移量找到对应的字符并添加到output列表中。
  9. 如果当前行不是第一行和最后一行,还需要添加下一行的字符。
  10. 最后将output列表转换为字符串并返回。

代码思路

  1. 首先计算字符串的长度n和行数N。

  2. 如果字符串长度为1或行数为1,直接返回原字符串。

       if n == 1 or N == 1:  # 如果字符串长度为1或行数为1,直接返回原字符串
                return s
    
  3. 计算中间行的间隔数S和每行的总字符数C。

     S = N-2  # 中间行的间隔数
     C = 2*N-2  # 每行的总字符数
    
  4. 计算完整循环的次数R和剩余的字符数RS。

    R = int(math.floor(n/C))  # 完整循环的次数
    RS = n % (C)  # 剩余的字符数
    
  5. 计算每行剩余的字符数CE和最后一行剩余的字符数RR。

    CE = n-R*C  # 每行剩余的字符数
    RR = 1 if (RS <= N) else 1+(RS-N)  # 最后一行剩余的字符数
    
  6. 计算最后一行的字符数RX。

     RX = R*(N-1) + RR  # 最后一行的字符数
    
  7. 初始化一个空列表output,用于存储转换后的字符。

  8. 使用两层循环遍历每一行和每一列,根据当前字符所在的行数和位置计算出其在原字符串中的偏移量offset,然后根据偏移量找到对应的字符并添加到output列表中。

        while i < N:
                j = 0
                k = (N-1-i)
                while j < RX:
                    r = int(math.floor(j/(N-1)))  # 当前字符所在的行数
                    rs = j % (N-1)  # 当前字符在该行的位置
                    offset = i if rs == 0 else N+rs-1  # 当前字符在原字符串中的偏移量
                    index = r*C+offset  # 当前字符在原字符串中的位置
                    if index < len(s):  # 如果该位置有字符,添加到输出列表中
                        output.append(s[index])
    
  9. 如果当前行不是第一行和最后一行,还需要添加下一行的字符。

     if i > 0 and i < N-1:  # 如果不是第一行和最后一行,还需要添加下一行的字符
                        r = int(math.floor(k/(N-1)))
                        rs = k % (N-1)
                        offset = i if rs == 0 else N+rs-1
                        index = r*C+offset
                        if index < len(s):
                            output.append(s[index])
                    j += (N-1)
                    k += (N-1)
                i += 1
    
  10. 最后将output列表转换为字符串并返回。

                 return ''.join(output)  # 将输出列表转换为字符串并返回

参考代码

import math
class Solution:
    def convert(self, s: str, numRows: int) -> str:
        n = len(s)
        N = numRows
        if n == 1 or N == 1:
            return s
        S = N-2
        C = 2*N-2
        R = int(math.floor(n/C))
        RS = n % (C)
        CE = n-R*C
        RR = 1 if (RS <= N) else 1+(RS-N)
        RX = R*(N-1) + RR
        output = []
        i = 0
        while i < N:
            j = 0
            k = (N-1-i)
            while j < RX:
                r = int(math.floor(j/(N-1)))
                rs = j % (N-1)
                offset = i if rs == 0 else N+rs-1
                index = r*C+offset
                if index < len(s):
                    output.append(s[index])
                if i > 0 and i < N-1:
                    r = int(math.floor(k/(N-1)))
                    rs = k % (N-1)
                    offset = i if rs == 0 else N+rs-1
                    index = r*C+offset
                    if index < len(s):
                        output.append(s[index])
                j += (N-1)
                k += (N-1)
            i += 1
        return ''.join(output)
# %%
s = Solution()
print(s.convert('PAYPALISHIRING', 3))

你可能感兴趣的:(算法练习笔记(Python版),python,算法,数据结构,动态规划,最小二乘法)