解题思路
这是一个错误记录统计问题。需要处理文件名和行号,统计错误出现次数,并按要求排序输出。
关键点:
- 提取文件名(去除路径,截取最后16个字符)
- 使用 统计错误出现次数
- 保持输入顺序用于相同次数的排序
- 最多输出8条记录
算法步骤:
- 处理输入的文件名和行号
- 统计错误出现次数
- 按要求排序
- 输出前8条记录
代码
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
void solve() {
string line;
map<string, int> count; // 统计次数
vector<pair<string, int>> records; // 保持输入顺序
while (getline(cin, line)) {
// 处理文件名和行号
string filename = getFileName(line);
int lineNum = getLineNum(line);
string key = filename + " " + to_string(lineNum);
// 统计错误次数
if (count[key] == 0) {
records.push_back({key, 1});
}
count[key]++;
}
// 更新次数
for (auto& record : records) {
record.second = count[record.first];
}
// 按次数排序,相同次数保持原顺序
stable_sort(records.begin(), records.end(),
[](const pair<string, int>& a, const pair<string, int>& b) {
return a.second > b.second;
});
// 输出前8条记录
int limit = min(8, (int)records.size());
for (int i = 0; i < limit; i++) {
cout << records[i].first << " " << records[i].second << endl;
}
}
private:
string getFileName(const string& path) {
// 获取最后一个'\'或'/'后的文件名
size_t pos = path.find_last_of("\\/");
string filename = (pos == string::npos) ? path : path.substr(pos + 1);
// 获取空格前的文件名
pos = filename.find_first_of(" ");
filename = filename.substr(0, pos);
// 截取最后16个字符
if (filename.length() > 16) {
filename = filename.substr(filename.length() - 16);
}
return filename;
}
int getLineNum(const string& line) {
size_t pos = line.find_last_of(" ");
return stoi(line.substr(pos + 1));
}
};
int main() {
Solution solution;
solution.solve();
return 0;
}
import java.util.Scanner;
import java.util.*;
public class Main {
static class Solution {
private String getFileName(String path) {
// 获取最后一个'\'或'/'后的文件名
String[] parts = path.split("[/\\\\]");
String filename = parts[parts.length - 1];
// 获取空格前的文件名
filename = filename.split(" ")[0];
// 截取最后16个字符
if (filename.length() > 16) {
filename = filename.substring(filename.length() - 16);
}
return filename;
}
public void solve() {
Scanner sc = new Scanner(System.in);
Map<String, Integer> count = new LinkedHashMap<>();
List<String> order = new ArrayList<>();
while (sc.hasNextLine()) {
String line = sc.nextLine().trim();
if (line.isEmpty()) break;
// 处理文件名和行号
String[] parts = line.split(" ");
String filename = getFileName(parts[0]);
String key = filename + " " + parts[1];
// 统计错误次数
if (!count.containsKey(key)) {
order.add(key);
}
count.put(key, count.getOrDefault(key, 0) + 1);
}
// 按次数排序,相同次数保持原顺序
order.sort((a, b) -> {
int countCompare = count.get(b).compareTo(count.get(a));
return countCompare != 0 ? countCompare :
order.indexOf(a) - order.indexOf(b);
});
// 输出前8条记录
int limit = Math.min(8, order.size());
for (int i = 0; i < limit; i++) {
System.out.println(order.get(i) + " " + count.get(order.get(i)));
}
sc.close();
}
}
public static void main(String[] args) {
new Solution().solve();
}
}
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class Solution:
def getFileName(self, path):
# 获取最后一个'\'或'/'后的文件名
filename = path.split('\\')[-1].split('/')[-1]
# 获取空格前的文件名
filename = filename.split()[0]
# 截取最后16个字符
return filename[-16:] if len(filename) > 16 else filename
def solve(self):
count = {} # 统计次数
order = [] # 保持输入顺序
try:
while True:
line = input().strip()
if not line:
break
# 处理文件名和行号
parts = line.split()
filename = self.getFileName(parts[0])
lineNum = parts[1]
key = f"{filename} {lineNum}"
# 统计错误次数并保持顺序
if key not in count:
order.append(key)
count[key] = count.get(key, 0) + 1
except EOFError:
pass
# 转换为记录列表并排序
records = [[key, count[key]] for key in order]
records.sort(key=lambda x: (-x[1], order.index(x[0])))
# 输出前8条记录
for key, cnt in records[:8]:
print(f"{key} {cnt}")
if __name__ == "__main__":
Solution().solve()
算法及复杂度
- 算法:哈希表 + 排序
- 时间复杂度:,主要是排序的时间复杂度
- 空间复杂度:,需要存储所有不重复的错误记录