环形缓冲区在数据结构中是一种特殊的线性数据结构,具有以下特点和优势:
https://www.nowcoder.com/practice/2baa6aba39214d6ea91a2e03dff3fbeb
开发一个简单错误记录功能小模块,能够记录出错的代码所在的文件名称和行号。
处理:
数据范围:错误记录数量满足 1≤n≤100 1≤n≤100 ,每条记录长度满足 1≤len≤100 1≤len≤100
输入描述:
每组只包含一个测试用例。一个测试用例包含一行或多行字符串。每行包括带路径文件名称,行号,以空格隔开。
输出描述:
将所有的记录统计并将结果输出,格式:文件名 代码行数 数目,一个空格隔开,如:
输入:
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
E:\je\rzuwnjvnuz 633
C:\km\tgjwpb\gy\atl 637
F:\weioj\hadd\connsh\rwyfvzsopsuiqjnr 647
E:\ns\mfwj\wqkoki\eez 648
D:\cfmwafhhgeyawnool 649
E:\czt\opwip\osnll\c 637
G:\nt\f 633
F:\fop\ywzqaop 631
F:\yay\jc\ywzqaop 631
D:\zwtymj\xccb\ljj\cqzlyaszjvlsjmkwoqijggmybr 645
输出:
rzuwnjvnuz 633 1
atl 637 1
rwyfvzsopsuiqjnr 647 1
eez 648 1
fmwafhhgeyawnool 649 1
c 637 1
f 633 1
ywzqaop 631 2
import sys
SIZE = 8
def formatFileName(f, size = 16):
if len(f) > size:
return f[-16:]
else:
return f
class RingBuffer:
def __init__(self, size) -> None:
self.buffer = []
self.legacy = []
self.head = 0
self.size = size
def put(self, item):
if item is not None: # 跳过已经淘汰的日志
for l in self.legacy:
if l["file"] == item["file"] and l["line"] == item["line"]:
return
if len(self.buffer) < self.size: # 缓冲区没有满,追加即可
self.buffer.append(item)
else: # 缓冲区已满,把要添加的元素放到队尾
self.legacy.append(self.buffer[self.head]) # 记录已经淘汰的日志
self.buffer[self.head] = item
self.head = (self.head + 1) % self.size
def findItem(self, file, line):
for idx, i in enumerate(self.buffer):
if i["file"] == file and i["line"] == line: # 文件名和行号都相同才可以
return idx
return None
def showItem(self, idx):
if idx < len(self.buffer):
return self.buffer[idx]
else:
return None
def updateItem(self, idx, key, value):
self.buffer[idx][key] = value
def print(self):
if not len(self.buffer):
return
headNode = self.buffer[self.head]
print(f'{headNode.get("file")} {headNode.get("line")} {headNode.get("count")}')
h = (self.head + 1) % len(self.buffer)
while (h != self.head):
node = self.buffer[h]
print(f'{node.get("file")} {node.get("line")} {node.get("count")}')
h = (h + 1) % len(self.buffer)
def filterLog(log):
if not log or not isinstance(log, str):
return None, None
[path, line] = log.split()
return path.split("\\")[-1], line
buffer = RingBuffer(SIZE)
for line in sys.stdin:
f, l = filterLog(line.strip())
if f is None or l is None:
continue
f = formatFileName(f) # 题目出的很奇怪,尾十六位相同的文件竟然被当成同一个文件
idx = buffer.findItem(f, l)
if idx is not None:
item = buffer.showItem(idx)
if item:
buffer.updateItem(idx, "count", item["count"] + 1)
else:
buffer.put({"file": f, "line": l, "count": 1})
buffer.print()