C ++:如何检查字符是否在给定的一组字符范围内?
比如,如果我有一个字符串名称。 我想检查此字符串的第一个字符是否在'a'到'n'之间。
我该怎么做?
要做(name[0] == 'a') (name[0] == 'b') ...会太长...
如果可能,我希望有一种可以优雅地处理ASCII值的解决方案。
C ++:如何检查字符是否在给定的一组字符范围内?
比如,如果我有一个字符串名称。 我想检查此字符串的第一个字符是否在'a'到'n'之间。
我该怎么做?
要做(name[0] == 'a') (name[0] == 'b') ...会太长...
如果可能,我希望有一种可以优雅地处理ASCII值的解决方案。
如果您想检查字符串的第一个字符是否在'a'和'n'之间,例如,检查 name[0] >= 'a' && name[0] <= 'n'
应该可以正确完成任务。
然而,请注意,如果您的字母的第一个字符也可能是大写的,则必须检查 (name[0] >= 'a' && name[0] <= 'n') || (name[0] >= 'A' && name[0] <= 'N')
。
std::all_of
与lambda表达式结合使用:std::all_of(name.begin(), name.end(), [](char i) { return (i >= 'a' && i <= 'z'); });
由于字符集通常遵循ASCII约定(如第2.3/14节所述),因此这对大多数应用程序来说是足够便携的:
基本源字符集成员的字形旨在识别与ASCII字符集对应的ISO/IEC 10646子集中的字符。然而,由于从源文件字符到源字符集的映射(在转换阶段1中描述)被指定为实现定义,因此必须记录实现如何在源文件中表示基本源字符。
上述算法的复杂度为O(n)
。另一种方法(检查每个字符是否为具有k
个字符的字符范围之一)是O(n*k)
,但至少您可以确定它不是实现定义的。
如果您确定平台上使用的字符集为ASCII,则可以使用以下内容:
if (std::all_of(name.begin(), name.end(), [](char c){return ((c >= 'a') && (c <= 'n'));}) ) {
// name contains only characters between 'a' and 'n' inclusive
}
if (name.find_first_not_of("abcdefghijklmn") == std::string::npos) {
// name contains only characters between 'a' and 'n' inclusive
}
bool is_in_range(char range_start, char range_end, char c)
{
static const char alphabet[] = "abcdefghijklmnopqrstuvwxyz";
unsigned int start_position = 0;
unsigned int end_position = 0;
unsigned int character_position = 0;
c = std::tolower(c);
for (unsigned int i = 0; i < sizeof(alphabet); ++i)
{
if (range_start == alphabet[i])
{
start_position = i;
}
if (range_end == alphabet[i])
{
end_position = i;
}
if (c == alphabet[i])
{
character_position = i;
}
}
bool result = false;
if (end_position <= start_position)
{
result = false;
}
else
{
if ((character_position >= start_position) && (character_position <= end_position))
{
result = true;
}
}
return result;
}
对于一段连续的字符范围,您可以:
_Bool isbetween(int c, int start, int end){
return ((unsigned)c-start < (end-start));
}
为了考虑大小写,使用 tolower()
和小写范围:
static inline int tolower(int c){
return c | ( ((unsigned)c-'A' < 26)<<5 );
}
//isbetween(tolower(x),'a','n');
对于非连续的范围,您可能需要创建一个掩码。在这个例子中,我将检查元音字母(为了简洁起见,因为只有5个,但是可以使用32个范围内的任何组合或者64个范围内的一些修改...实际上,在64位平台上使用64位掩码将消除大小写处理的需要)。
static const unsigned vowel_mask = (1<<('a'-'a'))
|(1<<('e'-'a'))|(1<<('i'-'a'))|(1<<('o'-'a'))|(1<<('u'-'a'));
int isvowel(int c){ //checks if c is a,A,e,E,i,I,o,O,u,U
unsigned x = (c|32)-'a';
return ((x<32)<<x)&vowel_mask;
}
&
比较代替。该方法在非ASCII系统上可能有效,具体取决于字符之间的分隔距离。isvowel:
or edi, 32 # tmp95,
xor eax, eax # tmp97
sub edi, 97 # x,
cmp edi, 31 # x,
setbe al #, tmp97
shlx eax, eax, edi # tmp99, tmp97, x
and eax, 1065233 # tmp96,
ret
Clang
isvowel: # @isvowel
or edi, 32
add edi, -97
mov eax, 32
xor ecx, ecx
cmp edi, eax
setb cl
shlx eax, ecx, edi
and eax, 1065233
ret
ICC
isvowel:
xor eax, eax #15.26
or edi, 32 #14.23
add edi, -97 #14.27
cmp edi, 32 #15.26
setb al #15.26
shlx eax, eax, edi #15.23
and eax, 1065233 #15.26
ret #15.26
除了标准的stackoverflow许可证外,此代码已发布到公共领域
遍历字符串,检查每个字符并查看它是否保持在a和n之间,使用str [i]>'a'和str [i]<'n'