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

改进用于确定可用值的strcmp() if/else阶梯结构

更高效的月份字符串转数值方案

当然有比嵌套if/else+反复调用strcmp()更优的方案,既能提升查找效率,又能简化代码、轻松处理缩写/大小写变体,下面是几种实用的实现思路:

1. 哈希表映射(O(1) 查找效率)

哈希表是最快的方案,查找时间复杂度接近常数。C标准库没有内置哈希表,但可以用轻量的第三方库(比如uthash)或者自己实现简单的哈希映射逻辑,把所有月份全称、缩写(如"March"、"MAR"、"Mar")和对应的数值绑定,一次查找就能得到结果。

示例代码(基于uthash):

#include <stdio.h>
#include <string.h>
#include "uthash.h"

typedef struct {
    char *name;
    int month;
    UT_hash_handle hh;
} MonthMap;

MonthMap *map = NULL;

void init_month_map() {
    // 批量插入所有月份的全称、缩写
    MonthMap entries[] = {
        {"January", 1}, {"Jan", 1}, {"JAN", 1},
        {"February", 2}, {"Feb", 2}, {"FEB", 2},
        {"March", 3}, {"Mar", 3}, {"MAR", 3},
        // ... 其他月份同理
        {"December", 12}, {"Dec", 12}, {"DEC", 12}
    };
    int i;
    for (i = 0; i < sizeof(entries)/sizeof(entries[0]); i++) {
        MonthMap *entry = malloc(sizeof(MonthMap));
        entry->name = strdup(entries[i].name);
        entry->month = entries[i].month;
        HASH_ADD_STR(map, name, entry);
    }
}

int get_month_from_str(const char *str) {
    MonthMap *entry;
    HASH_FIND_STR(map, str, entry);
    return entry ? entry->month : -1; // 找不到返回-1
}

// 使用示例
int main() {
    init_month_map();
    printf("%d\n", get_month_from_str("April")); // 输出4
    printf("%d\n", get_month_from_str("MAR")); // 输出3
    return 0;
}

优点:查找速度最快,添加/修改月份变体非常灵活;缺点:需要引入第三方哈希库,或者自己实现哈希函数(比如基于字符串首字符+长度的简单哈希)。

2. 预排序数组+二分查找(O(log n) 查找效率)

把所有月份名称(含缩写)存入结构体数组,提前排序后用标准库的bsearch()函数进行二分查找,效率远高于线性的if/else阶梯,代码也更整洁。

示例代码:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct {
    const char *name;
    int month;
} MonthEntry;

// 所有月份的全称、缩写,按字典序排序
MonthEntry month_list[] = {
    {"April", 4}, {"Apr", 4}, {"APR", 4},
    {"August", 8}, {"Aug", 8}, {"AUG", 8},
    {"December", 12}, {"Dec", 12}, {"DEC", 12},
    // ... 其他月份按字典序排列
    {"March", 3}, {"Mar", 3}, {"MAR", 3}
};

// 二分查找的比较函数
int compare_month(const void *a, const void *b) {
    return strcmp(((MonthEntry*)a)->name, ((MonthEntry*)b)->name);
}

int get_month_from_str(const char *str) {
    MonthEntry key = {str, 0};
    MonthEntry *result = bsearch(&key, month_list, sizeof(month_list)/sizeof(month_list[0]), sizeof(MonthEntry), compare_month);
    return result ? result->month : -1;
}

// 使用示例
int main() {
    printf("%d\n", get_month_from_str("February")); // 输出2
    printf("%d\n", get_month_from_str("Feb")); // 输出2
    return 0;
}

优点:无需第三方库,依赖标准库即可实现,代码可移植性强;缺点:数组必须提前按字典序排序,新增变体后需要重新排序。

3. 前缀分支优化(轻量场景首选)

如果不想引入额外数据结构,可以利用月份名称的前缀特征快速缩小范围,减少strcmp()的调用次数,代码比全量if/else简洁很多,同时提升效率。

示例代码:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// 先统一转小写,避免大小写敏感
void str_tolower(char *str) {
    while (*str) {
        *str = tolower((unsigned char)*str);
        str++;
    }
}

int get_month_from_str(char *str) {
    str_tolower(str);
    switch(str[0]) {
        case 'j':
            if (strcmp(str, "january") == 0 || strcmp(str, "jan") == 0) return 1;
            if (strcmp(str, "june") == 0 || strcmp(str, "jun") == 0) return 6;
            if (strcmp(str, "july") == 0 || strcmp(str, "jul") == 0) return 7;
            break;
        case 'f':
            if (strcmp(str, "february") == 0 || strcmp(str, "feb") == 0) return 2;
            break;
        case 'm':
            if (strcmp(str, "march") == 0 || strcmp(str, "mar") == 0) return 3;
            if (strcmp(str, "may") == 0) return 5;
            break;
        // ... 其他首字母分支同理
        case 'd':
            if (strcmp(str, "december") == 0 || strcmp(str, "dec") == 0) return 12;
            break;
    }
    return -1;
}

优点:无需额外数据结构,代码轻量,适合资源受限的场景;缺点:查找效率略低于前两种方案,新增变体需要手动修改分支。

另外,无论用哪种方案,建议先将输入字符串统一转为小写(或大写),避免大小写敏感的问题,比如把"MAR"、"Mar"都转为"mar"再匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 13:20:32