简体   繁体   English

如何检查字符是否在给定的字符范围内?

[英]How do I check if a character is in a given range of characters?

C++: How do i check if a character is between a given range of characters? C ++:如何检查字符是否在给定范围的字符之间?

Say, if I have a string name. 说,如果我有一个字符串名称。 I want to check if the first character of this string is between 'a' to 'n'. 我想检查这个字符串的第一个字符是否在'a'到'n'之间。

How do I do it? 我该怎么做?

To do (name[0] == 'a') (name[0] == 'b')... would be too long... 要做(名称[0] =='a')(名称[0] =='b')...太长了...

If possible, I would like a solution that deals with ASCII values elegantly. 如果可能的话,我想要一个优雅地处理ASCII值的解决方案。

If you want to check whether or not the first character of you string is between 'a' and 'n', for instance, checking name[0] >= 'a' && name[0] <= 'n' should do the job properly. 例如,如果要检查字符串的第一个字符是否在“a”和“n”之间,检查name[0] >= 'a' && name[0] <= 'n'应该执行工作得当。

Keep in mind, however, that if you can also have caps as a first character in your letter, you have to check (name[0] >= 'a' && name[0] <= 'n') || (name[0] >= 'A' && name[0] <= 'N') 但请记住,如果你也可以在封信中加上大写作为第一个字符,你必须检查(name[0] >= 'a' && name[0] <= 'n') || (name[0] >= 'A' && name[0] <= 'N') (name[0] >= 'a' && name[0] <= 'n') || (name[0] >= 'A' && name[0] <= 'N') instead. (name[0] >= 'a' && name[0] <= 'n') || (name[0] >= 'A' && name[0] <= 'N')

You can use std::all_of in combination with a lambda expression : 您可以将std::all_oflambda表达式结合使用:

std::all_of(name.begin(), name.end(), [](char i) { return (i >= 'a' && i <= 'z'); });

Live demo 现场演示

This is portable enough for most application, since the character set is usually implemented following the ASCII conventions as explain in §2.3/14: 这对于大多数应用程序来说足够便携,因为字符集通常遵循ASCII约定来实现,如§2.3/ 14中的解释:

The glyphs for the members of the basic source character set are intended to identify characters from the subset of ISO/IEC 10646 which corresponds to the ASCII character set. 基本源字符集成员的字形旨在识别ISO / IEC 10646子集中对应于ASCII字符集的字符。 However, because the mapping from source file characters to the source character set (described in translation phase 1) is specified as implementation-defined, an implementation is required to document how the basic source characters are represented in source files. 但是,由于源文件字符到源字符集(在转换阶段1中描述)的映射被指定为实现定义,因此需要实现来记录源文件中基本源字符的表示方式。

The complexity of the above algorithm is O(n) . 上述算法的复杂性为O(n) The alternative (check every character to be one in the character range with k characters) is O(n*k) , but at least you can be sure it's not implementation defined. 另一种方法(在k字符的字符范围内检查每个字符为1)是O(n*k) ,但至少可以确定它不是实现定义的。

If you're sure the used character set on your platform(s) is ASCII, you can use something like : 如果您确定平台上使用的字符集是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
}

Otherwise, something like this should do the trick : 否则,这样的事情应该做的伎俩:

if (name.find_first_not_of("abcdefghijklmn") == std::string::npos) {
    // name contains only characters between 'a' and 'n' inclusive
}

An old fashioned portable method: 一种老式的便携方法:

    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;
}

循环遍历字符串,检查每个字符,看看它是否使用str [i]>'a'和str [i] <'n'保持在a和n之间

For a contiguous range of characters you can: 对于连续的角色范围,您可以:

_Bool isbetween(int c, int start, int end){
  return ((unsigned)c-start < (end-start));
}

To account for case, use tolower() and the lower case range: 要考虑案例,请使用tolower()和小写范围:

static inline int tolower(int c){
  return c | ( ((unsigned)c-'A' < 26)<<5 );
}
//isbetween(tolower(x),'a','n');

For a non-contiguous range, you may need to create a mask. 对于非连续范围,您可能需要创建一个掩码。 In this example, I will check for vowels (for brevity because there are only 5, but any combination in a range of 32 could be used or 64 with some modifications ... in fact, a 64 bit mask on a 64 bit platform would eliminate the need for case handling). 在这个例子中,我将检查元音(为简洁起见,因为只有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;
}

Note that these implementations contain no branches; 请注意,这些实现不包含分支; however the use of unsigned comparison may prevent automatic compiler vectorization (intel intrinsics, don't have unsigned compare) ... if that is your goal, you can use 2 & ed comparisons instead. 但是使用无符号比较可能会阻止自动编译器矢量化(英特尔内在函数,没有无符号比较)...如果这是你的目标,你可以使用2 & ed比较。 This method may or may not work on non-ascii systems depending on the separation distance of the characters. 根据字符的分隔距离,此方法可能适用于非ascii系统,也可能不适用。

GCC GCC

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 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

In addition to the standard stackoverflow license, this code is released to the Public Domain 除了标准的stackoverflow许可证之外,此代码还将发布到Public Domain

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何限制字符输入范围? - How do I limit the character Input range? 如何检查角色是否在范围内 - How to check if a character is within a range 如何有效地将数组的一系列值与给定数字相乘? - How do I efficiently multiply a range of values of an array with a given number? 如何找到给定数字的频率进入数组的范围? - How do I find the frequency of a given number into a range into an array? 如何用转义字符替换字符串中的所有特殊字符? - How do I replace all special characters in a string with the escape character? 如何在Xcode中使用Unicode打印字符╔(和其他字符)? - How do I print the character ╔ (and other characters) using Unicode in Xcode? 如何检查给定文件是否存在依赖项错误? - How do I check whether given files have dependency bugs? 如何在 cpp 中检查给定输入的数据类型? - how do I check the data type of the given input in cpp? 如何检查字符常量是否符合ASCII? - How do I check whether character constants conform to ASCII? 如何在不完整搜索并使用检查功能的情况下生成给定范围内的素数回文? - How can I generate prime palindromes in a given range without complete searching it and using a check function?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM