题解 | 简单错误记录
简单错误记录
https://www.nowcoder.com/practice/2baa6aba39214d6ea91a2e03dff3fbeb
#include <stdio.h>
#include <string.h>
#define T 100 // 最大记录条数
int main() {
// 定义变量
char s[100]; // 存储单条输入的路径字符串
char s1[T][17] = {0}; // 存储处理后的文件名(16字符+结束符\0)
int y[T]; // 存储每条记录对应的行号
int j = 0; // 有效记录的下标(去重后的记录索引)
int t = 0; // 总读取记录的条数(所有输入的记录数)
int num[T]; // 存储每条有效记录的行号(和原行号一致)
int time[T]; // 存储每条不重复记录的出现次数
// 初始化次数数组:所有记录默认出现1次
for (int k = 0; k < T; k++)
time[k] = 1;
// ===================== 1. 循环读取输入 =====================
// 读取路径s和行号y[t],直到输入结束
while (scanf("%s %d", s, &y[t]) != EOF) {
// 判断是否是合法Windows路径(格式:X:\...)
if (s[0] >= 'A' && s[0] <= 'Z' && s[1] == ':' && s[2] == '\\') {
int len = strlen(s); // 获取路径字符串长度
int i = 3, name = 2; // name:记录最后一个\的位置,初始为2
int q = 0; // 文件名复制的下标
// 遍历路径,找到【最后一个】\ 的位置,存入name
for (i = 3; i < len; i++) {
if (s[i] == '\\') {
name = i;
}
}
// ===================== 2. 截取文件名 =====================
// 如果最后一个\离末尾≤16字符:从\后一位开始复制到末尾
if (name >= len - 16) {
for (; name < len - 1; name++) {
s1[j][q++] = s[name + 1]; // 复制\后面的字符
}
}
// 否则:只截取字符串最后16个字符作为文件名
else {
for (name = len - 16; name < len; name++) {
s1[j][q++] = s[name];
}
}
s1[j][q] = '\0'; // 给文件名添加字符串结束符,防止乱码
num[j] = y[t]; // 保存当前记录的行号
j++; // 有效记录数+1
t++; // 总读取记录数+1
}
}
// ===================== 3. 去重 + 统计次数 =====================
// 双重循环:比较所有记录,重复的只保留第一条
for (int i = 0; i < t; i++) {
for (int j = i + 1; j < t; j++) {
// 如果【文件名相同 + 行号相同】,判定为重复记录
if (strcmp(s1[i], s1[j]) == 0 && num[i] == num[j]) {
s1[j][0] = '\0'; // 清空后面重复的文件名
num[j] = 0; // 标记重复记录为无效
time[i]++; // 第一条记录的出现次数+1
time[j] = 0; // 重复记录次数置0
}
}
}
// ===================== 4. 按要求输出(正序+最后8条) =====================
int printed = 0; // 记录已输出的条数
int total = 0; // 统计总有效记录数
// 第一步:统计所有有效记录的总数
for (int i = 0; i < t; i++)
if (num[i] != 0)
total++;
// 如果有效记录≤8条:直接正序全部输出
if (total <= 8) {
for (int i = 0; i < t; i++) {
if (num[i] != 0) { // 只输出有效记录
printf("%s %d %d\n", s1[i], num[i], time[i]);
printed++;
}
if (printed > 7) { // 最多输出8条
break;
}
}
}
// 如果有效记录>8条:正序输出【最后8条】
else {
int cnt = 0; // 遍历有效记录的计数
// 正序遍历所有记录
for (int i = 0; i < t; i++) {
if (num[i] != 0) { // 只判断有效记录
// 跳过前面的记录,只输出最后8条
if (cnt >= total - 8) {
printf("%s %d %d\n", s1[i], num[i], time[i]);
}
cnt++; // 有效记录计数+1
}
}
}
return 0;
}
题目需求
输入多行Windows 路径 + 行号,要求:
- 提取路径中文件名(最后一个
\后面的部分) - 文件名只保留最后 16 个字符
- 文件名 + 行号完全相同的记录算重复,只保留第一次出现的,并统计出现次数
- 正序输出,最多输出最后 8 条不重复记录
解题步骤(4 大步)
- 读取输入:循环读取路径和行号,直到输入结束
- 处理文件名:找到最后一个
\,截取有效文件名(最多 16 字符) - 去重统计:遍历所有记录,重复的只保留第一条,统计重复次数
- 输出结果:正序输出,不足 8 条全输出,超过 8 条只输出最后 8 条
查看26道真题和解析