最近使用python做了华为上机题:简单错误记录,在过程中遇到了一些问题,最后找到了解决办法。
问题原因主要包括两方面:一是对于牛客网的oj系统不够深入了解,导致一些测试case输入问题;二是对python2和python3的差别了解的不够深入,特别是对于字典的使用。
一、思路分析
本题主要使用哈希表映射实现,用到python中的dict结构。首先想到了使用dict = {文件名:{'行号':23,'计数':5}}这类字典,但是能够记录相同文件名,不同行号的情况。后来,使用dict = {文件名 行号:计数}这类字典进行记录,在最后输出时再拆分文件名和错误行号。
二、遇到的问题
问题(1):不知道输入多少行错误记录,且需要读入所有的错误记录后再输出结果,不能使用for i in range(M): M为一般题目中会给出的测试样例个数。
解决:
for line in sys.stdin:
# line 即为每条输入的记录
问题(2):最多输出8条数据。由于不知道最后的字典是否记录了满8条数据,不能使用for i in range(8):进行循环输出。
解决:设置count,不断计数,再进行输出,满足8条时停止遍历字典。
count = 0
for key in my_error_record:
if count > 7:
break
# 输出
问题(3):普通字典和collections.OrderedDict()的区别,本题中使用普通字典不能通过,换为排序字典后可以。
详解:观察两类字典的不同之处。普通字典是无序的,后续会加以补充。
问题(4):为了避免有多个case循环输入,外围加while True循环输入,最后运行超时。
解决:在此类题目中,只会输入一个case,不断的记录错误条数,因此不必加循环读入模块,会陷入死循环。
问题(5):输出一个数组res的最后N个元素,不管res的长度是否超过N,都可以直接输出res[-N:],不必判断len(res)和N的大小。
问题(6): 对字典进行values排序后,变为list类型,不能通过dict.items()访问。
在本题中,将字典记录好之后,要按照错误的条数进行排序。访问字典时,不能同时访问key和value,因为此时的my_error_record 已经不是一个字典,而是list类型。
例如:
>>> a = {'a':3,'b':7,'c':0}
>>> b = sorted(a.items(),key = lambda x :x[1])
>>> b
[('c', 0), ('a', 3), ('b', 7)]
my_error_record = sorted(error_record.items(),key = lambda x:x[1],reverse=True)
for key,value in my_error_record.items(): # 出现错误,list类型没有迭代
最后的python2 AC代码如下:
# _*_ coding:utf-8 _*_
import sys
import collections
error_record = collections.OrderedDict()
# 建立有效的字典
# dict = {文件名:{'行号':23,'count':5}},不可用,
#无法记录相同文件名,不同行号的的记录
# dict = {文件名 行号:count}
# 不知到有多少行输入数据,且需要处理完所有输入数据后再输出结果
for line in sys.stdin:
# ele = line.split('\\')[-1].strip('\n')
file_row = line.strip().split('\\')[-1]
if file_row in error_record:
error_record[file_row] += 1
else:
error_record[file_row] = 1
# 对字典进行values排序,字典排序后,变为list类型,不能通过dict.items()访问
my_error_record = sorted(error_record.items(),key = lambda x:x[1],reverse=True)
# 输出不超过8行的数据,不确定字典是否有8条数据
count = 0
for key in my_error_record:
if count > 7:
break
file,row = key[0].split()
value = key[1]
count += 1
print file[-16:],row, value
'''
加入while结构,超时,不加能通过
import sys
import collections
while True:
try:
lst = []
dct = collections.OrderedDict()
for line in sys.stdin:
# ele = line.split('\\')[-1].strip('\n')
ele = line.strip().split('\\')[-1]
if ele in dct:
dct[ele] = dct[ele] + 1
else:
dct[ele] = 1
#对字典按照出现次数(value)排序
lstTuple = sorted(dct.items(), key = lambda d:d[1], reverse = True)
#输出不超过8行的结果
count = 0
for key in lstTuple:
if count > 7:
break
count = count + 1
#文件名取后16位
if len(key[0].split(' ')[0]) > 16:
print key[0].split(' ')[0][-16:], key[0].split(' ')[1], key[1]
else:
print key[0].split(' ')[0], key[0].split(' ')[1], key[1]
except:
break
'''