You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用scanf读取特定单词时循环无法退出导致TLE问题排查

解决你的单词统计程序TLE问题

看起来你的程序超时(TLE)主要有两个核心原因:scanf的EOF处理不严谨,以及单词匹配的效率太低。咱们一步步来修复:

1. 修复inputTextTxt的循环退出逻辑

你当前的inputTextTxt函数里,第一个scanf("%*[^a-zA-Z0-9_]")没有检查返回值。当输入到达EOF时,这个scanf会返回EOF,但代码会继续执行后面的读取操作。虽然理论上后续的scanf会返回EOF触发break,但在某些评测环境下,这种未处理的EOF可能导致循环重复执行无效的读取操作,浪费时间。

修改后的inputTextTxt应该在跳过非目标字符后立即检查EOF:

void inputTextTxt(void) {
    for (;;) {
        // 跳过非字母数字下划线,同时检查是否到达EOF
        int skip_status = scanf("%*[^a-zA-Z0-9_]");
        if (skip_status == EOF) {
            break;
        }
        int cnt = scanf("%2047[a-zA-Z0-9_]", tmp);
        if (cnt != 1) {
            break;
        }
        for (size_t i = 0; i < dic_actual_num; ++i) {
            if (strcmp(dicWord[i], tmp) == 0) {
                dicWcount[i]++;
            }
        }
    }
}

2. 优化单词匹配效率(关键解决TLE)

你现在的统计逻辑是每个文本单词遍历整个字典,时间复杂度是O(M*N)(M是文本单词数,N是字典大小)。当字典和文本规模较大时,这种线性遍历会非常慢,直接导致超时。

解决方法是把字典排序后用二分查找,不需要额外的库依赖:

步骤1:准备排序的字典条目

在main函数中,inputDicTxt执行完毕后,创建一个结构体数组保存字典单词和对应的计数指针,然后排序:

// 定义结构体保存字典条目
typedef struct {
    char* word;
    int* count_ptr;
} DictEntry;

int main() {
    inputDicTxt();
    
    // 为二分查找准备排序的字典条目
    DictEntry* sorted_entries = malloc(dic_actual_num * sizeof(DictEntry));
    for (int i = 0; i < dic_actual_num; ++i) {
        sorted_entries[i].word = dicWord[i];
        sorted_entries[i].count_ptr = &dicWcount[i];
    }
    
    // 排序字典条目(按单词字典序)
    int compare_entries(const void* a, const void* b) {
        const DictEntry* entry_a = (const DictEntry*)a;
        const DictEntry* entry_b = (const DictEntry*)b;
        return strcmp(entry_a.word, entry_b.word);
    }
    qsort(sorted_entries, dic_actual_num, sizeof(DictEntry), compare_entries);
    
    // 修改inputTextTxt的调用,传入排序后的条目和字典大小
    inputTextTxt(sorted_entries, dic_actual_num);
    
    // ... 后续的找最大值、输出、释放内存逻辑
    free(sorted_entries); // 别忘了释放这个数组
    return 0;
}

步骤2:修改inputTextTxt用二分查找

void inputTextTxt(DictEntry* sorted_entries, int dic_size) {
    for (;;) {
        int skip_status = scanf("%*[^a-zA-Z0-9_]");
        if (skip_status == EOF) {
            break;
        }
        int cnt = scanf("%2047[a-zA-Z0-9_]", tmp);
        if (cnt != 1) {
            break;
        }
        // 构造查找键
        DictEntry search_key = {.word = tmp};
        // 二分查找单词
        DictEntry* found = bsearch(&search_key, sorted_entries, dic_size, sizeof(DictEntry), compare_entries);
        if (found != NULL) {
            // 找到则计数+1
            (*(found->count_ptr))++;
        }
    }
}

这样每个单词的查找时间复杂度降到O(logN),整体统计效率会大幅提升,彻底解决超时问题。

3. 修复字典输入的分隔符判断逻辑

你的inputDicTxt里用strcmp(tmp, divider) >= 0来判断分隔符,这会把任何比-----长的-序列(比如------)误判为分隔符,导致字典输入提前结束,后续出现错误答案(WA)。应该改成精确匹配:

if (cnt_divider) {
    if (strcmp(tmp, divider) == 0) { // 这里改成==0,精确匹配5个'-'
        dicWcount = calloc(dic_actual_num, sizeof(*dicWcount));
        break;
    }
}

这些修改应该能同时解决你的TLE和潜在的WA问题。

内容的提问来源于stack exchange,提问作者LINPOHSIEN

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 07:29:35