c - 查找字符串是否为大小写混合的最有效方法

标签 c string algorithm optimization

假设我有很长的字符串,并且我想查看列是 allLower、allUpper 还是 mixedCase。例如以下列

text
"hello"
"New"
"items"
"iTem12"
"-3nXy"

文本将是 mixedCase。确定这一点的朴素算法可能是:

int is_mixed_case, is_all_lower, is_all_upper;
int has_lower = 0;
int has_upper = 0;
// for each row...for each column...
for (int i = 0; (c=s[i]) != '\0'; i++) {
    if (c >='a' && c <= 'z') {
        has_lower = 1;
        if (has_upper) break;
    }
    else if (c >='A' && c <= 'Z') {
        has_upper = 1;
        if (has_lower) break;
    }
}

is_all_lower = has_lower && !has_upper;
is_all_upper = has_upper && !has_lower;
is_mixed_case = has_lower && has_upper;

不过,我确信会有更高效的方法来做到这一点。执行此算法/计算的最有效方法是什么?

最佳答案

如果您知道将要使用的字符编码(我在代码示例中使用了 ISO/IEC 8859-15),查找表可能是最快的解决方案。这还允许您决定将扩展字符集中的哪些字符(例如 µ 或 ß)计为大写、小写或非字母。

char test_case(const char *s) {
    static const char alphabet[] = {
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  //  ABCDEFGHIJKLMNO
        1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,  // PQRSTUVWXYZ
        0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  //  abcdefghijklmno
        2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,  // pqrstuvwxyz
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
        0,0,0,0,0,0,0,1,0,2,0,2,0,0,0,0,  //        Š š ª
        0,0,0,0,0,1,2,0,0,2,0,2,0,1,2,1,  //      Žµ  ž º ŒœŸ
        1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,  // ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏ
        1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,  // ÐÑÒÓÔÕÖ ØÙÚÛÜÝÞß
        2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,  // àáâãäåæçèéêëìíîï
        2,2,2,2,2,2,2,0,2,2,2,2,2,2,2,2}; // ðñòóôõö øùúûüýþÿ
    char cases = 0;
    while (*s && cases != 3) {
        cases |= alphabet[(unsigned char) *s++];
    }
    return cases; // 0 = none, 1 = upper, 2 = lower, 3 = mixed
}

正如 chux 在评论中所建议的,您可以设置 alphabet[0] 的值到 4,然后你只需要一个条件 cases < 3在 while 循环中。

关于c - 查找字符串是否为大小写混合的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57682576/

相关文章:

javascript - meteor 辅助变量去除重复的相邻空格

C strcpy() 复制字符串文字而没有段错误

algorithm - 如何实现循环算法?

algorithm - 基于子集倒置的排序算法

javascript - 使用 lodash 简化表达式

c++ - 理解函数指针

c - ANSI C - 计算字符串指针的大小

c - 如何用其他字符替换字符串中的特定字符

c - 对异常大小的单词使用 mask

c++ - 在 C++ 中编码 std::string