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

如何更快验证3字符A/B/C大小写排列的字符串?C/C++方案均可

高效验证A/B/C排列(大小写不敏感)的实现方案

你的需求是验证长度为3的输入字符串是否是A、B、C的任意排列(支持大小写),同时兼容已有的2元素函数,且后续可扩展至4元素。现有实现通过字符串哈希+switch分支完成验证,这里提供更高效、易扩展的优化方案:

核心优化思路

  1. 位运算统一大小写:用& ~0x20快速将字符转大写(比条件判断更快);
  2. 位掩码合法性校验:通过位掩码判断输入恰好包含A、B、C各一个,无重复也无非法字符;
  3. 预查表返回排列:预存所有合法大写排列,通过字符索引直接定位,减少分支开销。

C++ 实现(支持返回对应大写排列)

#include <string_view>
#include <array>

constexpr char to_upper(char c) noexcept {
    return c & ~0x20; // 小写转大写,大写字符不变
}

std::string_view validateIndex(std::string_view s) noexcept {
    // 快速过滤长度不符的输入
    if (s.size() != 3) {
        return "";
    }

    const char c0 = to_upper(s[0]);
    const char c1 = to_upper(s[1]);
    const char c2 = to_upper(s[2]);

    // 计算位掩码:A对应第0位,B第1位,C第2位
    const uint8_t mask = (1 << (c0 - 'A')) | (1 << (c1 - 'A')) | (1 << (c2 - 'A'));
    // 掩码为0b111(7)说明恰好包含A、B、C各一个
    if (mask != 0b111) {
        return "";
    }

    // 预存所有合法排列
    static constexpr std::array<std::string_view, 6> permutations = {
        "ABC", "ACB", "BAC", "BCA", "CAB", "CBA"
    };

    // 字符转索引(A=0, B=1, C=2)
    const uint8_t idx0 = c0 - 'A';
    const uint8_t idx1 = c1 - 'A';
    const uint8_t idx2 = c2 - 'A';

    // 预定义索引映射表,直接定位排列
    static constexpr uint8_t perm_lookup[3][3][3] = {
        {{255, 0, 1},
         {2, 255, 3},
         {4, 5, 255}}
    };

    return permutations[perm_lookup[idx0][idx1][idx2]];
}

// 仅验证合法性的简化版本
bool validate(std::string_view s) noexcept {
    if (s.size() != 3) {
        return false;
    }

    const char c0 = to_upper(s[0]);
    const char c1 = to_upper(s[1]);
    const char c2 = to_upper(s[2]);

    const uint8_t mask = (1 << (c0 - 'A')) | (1 << (c1 - 'A')) | (1 << (c2 - 'A'));
    // 掩码验证+字符范围检查(避免非法字符导致的掩码巧合)
    return mask == 0b111 && c0 >= 'A' && c0 <= 'C' &&
           c1 >= 'A' && c1 <= 'C' && c2 >= 'A' && c2 <= 'C';
}

C 语言实现

#include <stdint.h>
#include <string.h>

static inline char to_upper(char c) {
    return c & ~0x20;
}

const char* validateIndex(const char* s) {
    if (strlen(s) != 3) {
        return "";
    }

    const char c0 = to_upper(s[0]);
    const char c1 = to_upper(s[1]);
    const char c2 = to_upper(s[2]);

    const uint8_t mask = (1 << (c0 - 'A')) | (1 << (c1 - 'A')) | (1 << (c2 - 'A'));
    if (mask != 0b111) {
        return "";
    }

    static const char* permutations[] = {"ABC", "ACB", "BAC", "BCA", "CAB", "CBA"};
    const uint8_t idx0 = c0 - 'A';
    const uint8_t idx1 = c1 - 'A';
    const uint8_t idx2 = c2 - 'A';

    static const uint8_t perm_lookup[3][3][3] = {
        {{255, 0, 1},
         {2, 255, 3},
         {4, 5, 255}}
    };

    return permutations[perm_lookup[idx0][idx1][idx2]];
}

// 仅验证合法性的简化版本
_Bool validate(const char* s) {
    if (strlen(s) != 3) {
        return 0;
    }

    const char c0 = to_upper(s[0]);
    const char c1 = to_upper(s[1]);
    const char c2 = to_upper(s[2]);

    const uint8_t mask = (1 << (c0 - 'A')) | (1 << (c1 - 'A')) | (1 << (c2 - 'A'));
    return (mask == 0b111) && (c0 >= 'A' && c0 <= 'C') &&
           (c1 >= 'A' && c1 <= 'C') && (c2 >= 'A' && c2 <= 'C');
}

扩展性说明

当需要扩展到4元素(如A/B/C/D)时,只需:

  1. 修改掩码为0b1111(15);
  2. 扩展排列数组,加入所有4元素的合法排列;
  3. 调整索引映射表的维度为4x4x4x4;
  4. 更新字符范围检查为c >= 'A' && c <= 'D'。

这种方案几乎不需要修改核心逻辑,扩展性极强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:15:54