我试图查找文本中最常用的单词。在我的程序中,我输入了一些文字。单词和文本由" -----"(我需要在我的程序中搜索最常用的单词)分开。
但是,我发现当程序在文本中搜索单词时。它似乎无法用完循环(我在PC ^ 2上超出了时间限制)。然后,我发现问题来自这个函数(如果我注释这个函数我得到了错误的答案错误)。我是否误解了scanf
的用法或错过了其他一些条件?
void inputTextTxt(void) {
for (;;) {
// toss all non-alpha-numerics
scanf("%*[^a-zA-Z0-9_]");
int cnt = scanf("%2047[a-zA-Z0-9_]", tmp);
if (cnt != 1) {
break; // or return
}
for (size_t i = 0; i < dic_actual_num; ++i) {
if (strcmp(dicWord[i], tmp) == 0) {
dicWcount[i]++;
}
}
}
}
char tmp[2048];
char **dicWord;
int *dicWcount;
int dic_assume_num = 1, dic_actual_num = 0;
void inputDicTxt() {
char divider[6] = "-----";
dicWord = malloc( dic_assume_num * sizeof( char* ));
for (;;) {
scanf("%*[^a-zA-Z0-9_-]");
int cnt_divider = scanf("%2047[-]", tmp);
int cnt_alphaNumerics = scanf("%2047[a-zA-Z0-9_]", tmp);
if (cnt_divider != 1 && cnt_alphaNumerics != 1)
break;
else if (cnt_divider) {
if (strcmp(tmp, divider) >= 0) {
dicWcount = calloc(dic_actual_num, sizeof(*dicWcount));
break;
}
}
else if (cnt_alphaNumerics) {
if (dic_actual_num >= dic_assume_num) {
dic_assume_num *= 2;
dicWord = realloc( dicWord, dic_assume_num * sizeof( char* ));
}
dicWord[dic_actual_num++] = strdup(tmp);
}
}
}
int main() {
inputDicTxt();
inputTextTxt();
int mostNum = 0;
for (int i = 0; i < dic_actual_num; ++i)
if (dicWcount[i] > dicWcount[mostNum])
mostNum = i;
// print out the most frequent word and its number
printf("%s %d\n", dicWord[mostNum], dicWcount[mostNum]);
for (int i = 0; i < dic_actual_num; ++i)
free(dicWord[i]);
free(dicWord);
free(dicWcount);
return 0;
}
编辑:我在代码中已从while(feof(!stdin))
更改为for(;;)
,但我仍然在判断系统上获得TLE
答案 0 :(得分:0)
我是否误解了
scanf
的用法或错过了其他一些条件?
请务必查看Why is “while ( !feof (file) )” always wrong? @alk
然而在这种情况下,代码以可接受的功能方式使用while (!feof(stdin))
几乎。所以这个问题可能在其他地方。 IAC,避免while (!feof(stdin))
的弱点和通常的IO问题的磁性。
目前尚不清楚为什么OP的代码处于明显的无限循环中(除了罕见的输入错误或其他UB,如tmp
太小) - 即使使用异常代码while (!feof(stdin)) {
。
下面是类似的代码,应该更干净地操作/调试。
OP以不稳定的方式使用while (!feof(stdin))
,如果代码循环而不读取字符,则会导致无限循环。示例:输入错误。
而不是while (!feof(stdin))
,检查保存数据的scanf()
的返回值。不要像if (scanf("%2047[a-zA-Z0-9_]", tmp)
那样简单地检查布尔值。检查它的价值。
void inputTextTxt(void) {
for (;;) {
// toss all non-alpha-numerics
scanf("%*[^a-zA-Z0-9_]");
char tmp[2048];
int cnt = scanf("%2047[a-zA-Z0-9_]", tmp);
if (cnt != 1) {
break; // or return
}
for (size_t i = 0; i < dic_actual_num; ++i) {
if (strcmp(dicWord[i], tmp) == 0) {
dicWcount[i]++;
// I'd expect a `break;` here as once a match is found,
// could another be found? Why keep looking?
}
}
}
}
迂腐地,像"%[a-z]"
这样的扫描集范围并未普遍实现 - 它是实现定义的行为。高度可移植的代码需要"%[abcedfghijklmnopqrstuvwxyz]"
。大多数系统都将"%[a-z]"
理解为希望,所以我怀疑这是OP的问题。
从样式的角度来看,if (scanf("%2047[^a-zA-Z0-9_]", tmp)); else if
具有误导性 - 它看起来像一个问题。如果代码仍然存在,请使用{;}
清楚地划分它。
if (scanf("%2047[^a-zA-Z0-9_]", tmp)) {
;
} else if ...