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

C语言歌曲名搜索如何实现关键词完整匹配,避免命中含该子串的长单词

歌曲关键词检索匹配问题修复方案

问题原因

当前代码使用strstr()做纯子串匹配,只要关键词出现在歌曲名任意位置就会命中,没有验证匹配到的内容是不是独立单词,才会出现搜索you命中含your的歌曲的问题。

修复思路

新增独立单词匹配校验规则,对strstr()找到的每一处匹配位置做边界校验:

  • 若匹配起始位置不是字符串开头,那么前一个字符必须是非英文字母(空格、标点、数字等都可)
  • 若匹配结束位置不是字符串结尾,那么后一个字符必须是非英文字母
    只要存在一处满足上述规则的匹配,就判定歌曲名符合搜索条件。

修复后代码

// 需额外引入 ctype.h 头文件使用isalpha()
#include <ctype.h>

// 新增独立单词匹配辅助函数
int is_full_word_match(const char *src_str, const char *keyword) {
    int key_len = strlen(keyword);
    int src_len = strlen(src_str);
    char *match_pos = src_str;
    
    // 循环查找所有可能的匹配位置
    while ((match_pos = strstr(match_pos, keyword)) != NULL) {
        int start_idx = match_pos - src_str;
        int end_idx = start_idx + key_len - 1;
        
        // 校验前边界:要么是开头,要么前一个字符不是字母
        int left_valid = (start_idx == 0) || (!isalpha((unsigned char)match_pos[-1]));
        // 校验后边界:要么是结尾,要么后一个字符不是字母
        int right_valid = (end_idx == src_len - 1) || (!isalpha((unsigned char)match_pos[key_len]));
        
        if (left_valid && right_valid) {
            return 1; // 找到符合要求的匹配
        }
        
        match_pos++; // 跳过当前位置继续查找下一处匹配
    }
    return 0; // 无符合要求的匹配
}

int main() {
    // 原有变量声明等逻辑保持不变
    printf("Enter the keyword: ");
    scanf("%s", keyWord);

    convert_to_lowercase(keyWord, keyWordLower);
    songCount = 0;

    for (i = 0; i < songNum; i++) {
        strcpy(listInfoLower, (listInfo + i)->name);
        convert_to_lowercase(listInfoLower, listInfoLower);
        // 替换原来的strstr判断
        if (is_full_word_match(listInfoLower, keyWordLower)) { 
            songCount++;
        }
    }
    if (songCount == 0) {
        printf("No songs with %s in database\n", keyWord);
    } else {
        printf("%d songs with %s\n", songCount, keyWord);
        for (i = 0; i < songNum; i++) {
            strcpy(listInfoLower, listInfo[i].name);
            convert_to_lowercase(listInfoLower, listInfoLower);
            // 同样替换判断逻辑
            if (is_full_word_match(listInfoLower, keyWordLower)) {
                printf("%s(%d) by %s, US(%d)\n", (listInfo + i)->name, (listInfo 
                    + i)->year, (listInfo + i)->artist, (listInfo + i)-> 
                    us_rank);
            }
        }
    }
    // 原有后续逻辑保持不变
    return 0;
}

补充说明

如果需要支持带特殊字符的关键词匹配,或者自定义单词分隔规则,可以修改边界校验的判断逻辑,把isalpha()替换成自定义的分隔符判断即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 14:45:03