题目
题目链接
描述
为了能快速从一篇文章中找出某个单词,可以记录下每个单词在文章出现的位置,称为单词的索引。
现在输入n行单词,统计输出每个单词出现在哪些行(行号从0开始计数)。另外为了对索引进行压缩,使用这样的方法记录单词出现的行数:如果只出现一次,就记录第一次出现的行数;如果出现两次及以上,记录第一次出现的行数,第二次及以后出现的行数用与前一次出现行数的差值表示。
输入
第一行整数n。
以下n行,每行一个单词,单词中不含空格。
输出
每一行按照“单词:第一次出现行数 第二次出现行数与第一次出现行数的差值 第三次出现行数与第二次出现行数的差值 ……”的格式输出单词的索引,例如“Self : 0 4 2”表示单词Self出现在第0行,第4行,第6行。
各行索引按照单词的词典序排列。
Code
错误示范
n=int(input)
lis=[]
for x in range(n):
name=input()
if name not in lis:
lis.append(name)
lis.append(x)
if name in lis:
lis.append(x)
代码解析
很明显没有写完,害
代码修正
n=int(input())
dic=dict()
for i in range(n):
name=input()
if name not in dic:
dic[name]=[i]
else:
for x in range(len(dic[name])):
i-=dic[name][x]
dic[name].append(i)
for key,value in sorted(dic.items()):
print(key+':',*value)
代码解析
这段代码的核心思路是统计一组单词在输入中出现的次数,并按照字典序输出每个单词和它们出现的位置。
具体的实现步骤如下:
- 创建一个空的字典
dic
,用于存储每个名字的出现位置。 - 使用一个循环,循环n次,读取每个名字并进行处理。
- 在循环内部,首先读取一个名字
name
。 - 如果该名字不在字典
dic
中,说明这个名字是第一次出现,将它作为字典的键,将一个包含现在的位置i
的列表作为它的值存入字典中。 - 如果名字已经在字典中,说明该名字之前已经出现过。
- 循环结束后,字典
dic
中存储了每个名字和它们出现的位置。 - 使用
sorted
函数对字典按照键进行排序,遍历排序后的键值对并输出每个名字和它们出现的位置。
核心思路就是利用字典的键值对来存储每个名字出现的位置,然后使用排序函数对字典按照键进行排序,并输出结果。
解题思路
这道题与另外一篇的4.第二个重复出现的数有点相似,都是使用了一个字典来存储键的一些属性,在这里值是代表单词出现的行数.
- 首先,我们应该先创建一个字典,按照你不在就加入,你在就往后增加的原则编写代码
- 其次,
- 我们利用第一行输入所给信息知道有多少行。
- 我们要注意到这里字典的值不同于
4.第二个重复出现的数
的一个数,而是列表,所以在第一次加入字典时,值要写成列表,继续添加的时候要用append
- 然后,我们还得注意在新添加的时候数值的用当前行减去前面所有已添加的数(因为一直添加的是与前一行的差值)
- 最后,
- 就是对输出格式的构造。我们要对字典散乱的键值对进行按照键的字母进行排序(字典是没有下标索引的 )我们用
for key,value in sorted(dic.items())
可以同时进行排序和获取键值; - 下面的print用到了解包,刚好可以满足按要求格式输出
- 就是对输出格式的构造。我们要对字典散乱的键值对进行按照键的字母进行排序(字典是没有下标索引的 )我们用
奇技淫巧
- Q:你不在就加入,你在就往后增加(自己创的说法哈)的原则下,如果值是列表怎么办?
–>加入的代码要写成=[]
;新增的代码要用到append()
- Q:单词出现多次新增的值要怎么计算?减去前面已存在的所有值怎么处理?
–>我们可以使用for循环-=
,循环次数就是现阶段列表的长度 - Q:既要对字典的键进行排序又要键和值一起输出该怎么处理?
–>我们可以使用items()
同时获取键和值分配给两个变量,同时在这个时候使用sorted函数对键进行排序 - Q:value值是一个列表,直接打印有
[]
,有什么办法可以消去括号同时每个元素间有空格呢?
–>如果使用join是不行的,不信可以自己去试试。所以我们可以使用*
解包列表,非常的方便