最近使用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
'''