理解题意非常重要,而理解题意要根据它举的例子,可根据它的例子也不一定能完全理解题意。
总之,一个测试用例中的记录不超过 100 条,如果两条错误记录截取后的文件名和错误行号相同,就认为是同一条记录,以该记录第一次出现为基准,将错误发生次数 +1,而不再添加新的记录。
最后,如果错误记录超过 8条,就输出整理后的最新记录的 8条错误记录,否则全部输出。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* 返回septor最后一次出现位置后的子字符串,并作规范化处理:
即如果字串长度大于16,只保留最后 16 位*/
static char* strlaststr(const char* str, const char septor);
int main() {
char str[100][100];
int lnum[100] = {0},
count[100] = {0},
i = 0; // 最后一条记录的位置
char septor = '\\';
char* st; // 临时字符串指针
int flag = 0; // 重复记录标记
// Initiate
if (scanf("%s %d", str[i], &lnum[i]) != EOF) {
st = strlaststr(str[i], septor);
strcpy(str[i], st);
count[i++] = 1;
}
while (scanf("%s %d", str[i], &lnum[i]) != EOF) {
char* st = strlaststr(str[i], septor);
for (int j = 0; j < i; j++) {
if (strcmp(st, str[j]) == 0 && lnum[j] == lnum[i]) { // 文件名相同
count[j] ++;
flag = 1;
}
}
if (flag == 1) {
flag = 0;
continue;
}
if (i < 100) {
strcpy(str[i], st);
count[i++] += 1;
} else { // 记录已满,有新记录,整体前移,覆盖旧记录
for (int j = 1; j < 100; j++) { // 记录前移
strcpy(str[j - 1], str[j]);
count[j - 1] = count[j];
lnum[j - 1] = lnum[j];
}
memset(str[7], '\0', sizeof(str[7])) ;
strcpy(str[99], st); // 添加新记录
count[99] = 1;
i = 99;
}
}
if ( i < 8) {
for (int j = 0; j < i; j++) {
printf("%s %d %d\n", str[j], lnum[j], count[j]);
}
} else {
for (int j = i - 8; j < i; j++) {
printf("%s %d %d\n", str[j], lnum[j], count[j]);
}
}
return 0;
}
static char* strlaststr(const char* str, const char septor) {
char* s = str;
if (str == NULL)
return NULL;
int len = strlen(s);
char* ss;
int i;
for (i = len - 1; i >= 0 && s[i] != septor; --i); // 定位 septor 的位置
if (i == -1) { // 没找到 septor,返回有效字符串
if (len > 16) {
ss = s + len - 16;
return ss;
}
}
// 找到 septor,返回其后有效字符串
if (len - i - 1 > 16) { // 子字符串长度大于 16
ss = s + len - 16;
return ss;
} else {
ss = s + i + 1;
return ss;
}
}

京公网安备 11010502036488号