题目要求:
给出一段字符串,其中包括时间和歌词,按照时间的顺序进行输出歌词。
歌词样式如下:
musicLrc = """[00:03.50]传奇
[00:19.10]作词:刘兵 作曲:李健
[00:20.60]演唱:王菲
[00:26.60]
[04:40.75][02:39.90][00:36.25]只是因为在人群中多看了你一眼
[04:49.00]
[02:47.44][00:43.69]再也没能忘掉你容颜
[02:54.83][00:51.24]梦想着偶然能有一天再相见
[03:02.32][00:58.75]从此我开始孤单思念
[03:08.15][01:04.30]
[03:09.35][01:05.50]想你时你在天边
[03:16.90][01:13.13]想你时你在眼前
[03:24.42][01:20.92]想你时你在脑海
[03:31.85][01:28.44]想你时你在心田
[03:38.67][01:35.05]
[04:09.96][03:39.87][01:36.25]宁愿相信我们前世有约
[04:16.37][03:46.38][01:42.47]今生的爱情故事 不会再改变
[04:24.82][03:54.83][01:51.18]宁愿用这一生等你发现
[04:31.38][04:01.40][01:57.43]我一直在你身旁 从未走远
[04:39.55][04:09.00][02:07.85]
"""
分析问题:
- 首先要将字符串分段输出,则需要将字符串分行处理,得到一行一行的字符之后,再对行处理。
- 当我们得到一行一行的数据之后我们需要考虑的是如何将时间和歌词进行分隔开来方便我们处理时间和输出歌词。
- 当我们将歌词与时间分隔开之后我们需要考虑的是如何将时间字符串转换成我们想要的整型可以操作的数据
- 当我们已经得到可以操作的时间顺序之后我们就该根据时间让其停顿输出歌词。
- 当我们以上四点全部做到那么我们就能够进行输出歌词了。
解决问题:
- 首先第一步我们得到一行一行的数据:通过字符串的函数 splitlines() 我们就可以得到一行一行的数据列表。
- 对歌词与时间的分隔:首先我们想到split()可以对数据分隔开,这样就可以处理了,但是我们得到的数据是不方便处理的而且还不好选择分隔符号,所以我们要对时间旁边的 " [ ] " 进行处理。我们可以用replace()将多余的符号替换成空字符,然后再对其分隔,所以我们先将 " [ " 替换成空字符,然后对 " ] " 进行分隔这个时候我们就能得到的就是分隔开之后的数据。
- 当我们得到数据的时候我们要将数据先临时保存下来然后再对数据操作,我们存下的数据是 “ 时间 ” “ 歌词 ”,所以我们可以用字典的形式对其存储。
- 当我们存储的时候我们就要求出时间的间隔段,所以我们就要用一个列表来保存时间,来排序,然后再进行数据处理得到停顿时间,然后就可以进行遍历的操作。
解题中出现的问题:
- 在存到字典的过程中我们一行中有多个时间段的处理: 我们可以先得出一个时间出现的次数 然后再存入字典中对其循环的输入。
- 停顿时间的处理,一开始第三秒才出现歌词,所以在时间的处理中我们需要注意第一次,而且注意:字典是无须的 输出的时候是有顺序的,我们在进行操作之前要对其进行排序。
- 其他的一些处理小细节也要多注意,在处理中我们数据类型的变化。
实现代码:
import time
musicLrc = """[00:03.50]传奇
[00:19.10]作词:刘兵 作曲:李健
[00:20.60]演唱:王菲
[00:26.60]
[04:40.75][02:39.90][00:36.25]只是因为在人群中多看了你一眼
[04:49.00]
[02:47.44][00:43.69]再也没能忘掉你容颜
[02:54.83][00:51.24]梦想着偶然能有一天再相见
[03:02.32][00:58.75]从此我开始孤单思念
[03:08.15][01:04.30]
[03:09.35][01:05.50]想你时你在天边
[03:16.90][01:13.13]想你时你在眼前
[03:24.42][01:20.92]想你时你在脑海
[03:31.85][01:28.44]想你时你在心田
[03:38.67][01:35.05]
[04:09.96][03:39.87][01:36.25]宁愿相信我们前世有约
[04:16.37][03:46.38][01:42.47]今生的爱情故事 不会再改变
[04:24.82][03:54.83][01:51.18]宁愿用这一生等你发现
[04:31.38][04:01.40][01:57.43]我一直在你身旁 从未走远
[04:39.55][04:09.00][02:07.85]
"""
time_list = []#得到时间的列表
sleep_time = []#停顿时间
musicDicet = {}#字典存储数据
time_miao = [] #得到时间的列表
fist_splines = [] #第一次切割之后的数据
fist_splines = musicLrc.splitlines() #得到一行一行的数据了
for x in fist_splines: #对其一行行的读取
time_num = x.count("[") #time_num这个是统计一行中有多少个时间数据
x = x.replace("[", "") #去掉数据里的" [ "
fist_splines = x.split("]") #分隔数据
#在这里 我们如果时间列表中有空格什么的 我们可以用 strip对数据进行处理要不下边的数据处理会出错,这#里没有空格 就没有处理,也可以用替换的方法 将空格替换成空字符处理
for y in range(time_num): #通过for循环将一行中的是所有时间当成key存到字典中
musicDicet[fist_splines[y]] = fist_splines[-1]
fen = int(fist_splines[y][:2]) #为了方便这里就用切片处理,可以使用分隔得到列表在进行处理
miao = float(fist_splines[y][3:]) #得到的是 分钟 和 秒
time_miao.append(fen * 60 + miao) #按照秒存入我们的列表中
time_miao = sorted(time_miao) # 这个时候我们得到的是一个无序的秒列表 需要对秒进行排序
for x in range(len(time_miao)): #得到是停顿的时间
if x == 0: #当他是第一个的时候 我们第一次停的时间是他本身
sleep_time.append( time_miao[x])
else:
sleep_time.append( time_miao[x] - time_miao[x-1]) #其他都是后一个减去前一个
musicDicet = sorted(musicDicet.items(), key=lambda e:e[0])#对字典按照key值进行排序 得到的是list 里面是元组 这里注意 字典输出时是有序的 但是它的存储是无序的
for x,y in enumerate(musicDicet): #返回下标和元组,sleep_time 来停止时间进行输出。
time.sleep(sleep_time[x])
print(y[0],y[1])
小结:
以上就是整个程序的流程,我们在解决问题的时候要有逻辑思维,这种逻辑思维最好的训练方法就是逆推的办法,
比如在这个程序中,我们想要歌词按时间打印,首先我们就要得到停顿时间才能按时间打印,其次我们打印的时候要得到时间的数据和歌词的数据,得到时间的数据和歌词的数据我们就要对数据进行处理从中得到想要的数据,所以需要将每一行的数据分隔成时间和歌词,我们需要得到每行的数据就需要对字符串分隔处理得到每行的数据。
所有的程序按照从上到下的顺序可能没有思路,我们可以从需求到推出我们一步步需要做什么这样的话就把问题解决了
代码中可能有不足的地方,不过基本的功能实现了,我也对其稍微的优化了。