[英]How do I check if a character is in a given range of characters?
C ++:如何檢查字符是否在給定范圍的字符之間?
說,如果我有一個字符串名稱。 我想檢查這個字符串的第一個字符是否在'a'到'n'之間。
我該怎么做?
要做(名稱[0] =='a')(名稱[0] =='b')...太長了...
如果可能的話,我想要一個優雅地處理ASCII值的解決方案。
例如,如果要檢查字符串的第一個字符是否在“a”和“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')
。
您可以將std::all_of
與lambda表達式結合使用:
std::all_of(name.begin(), name.end(), [](char i) { return (i >= 'a' && i <= 'z'); });
這對於大多數應用程序來說足夠便攜,因為字符集通常遵循ASCII約定來實現,如§2.3/ 14中的解釋:
基本源字符集成員的字形旨在識別ISO / IEC 10646子集中對應於ASCII字符集的字符。 但是,由於源文件字符到源字符集(在轉換階段1中描述)的映射被指定為實現定義,因此需要實現來記錄源文件中基本源字符的表示方式。
上述算法的復雜性為O(n)
。 另一種方法(在k
字符的字符范圍內檢查每個字符為1)是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;
}
循環遍歷字符串,檢查每個字符,看看它是否使用str [i]>'a'和str [i] <'n'保持在a和n之間
對於連續的角色范圍,您可以:
_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;
}
請注意,這些實現不包含分支; 但是使用無符號比較可能會阻止自動編譯器矢量化(英特爾內在函數,沒有無符號比較)...如果這是你的目標,你可以使用2 &
ed比較。 根據字符的分隔距離,此方法可能適用於非ascii系統,也可能不適用。
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
鐺
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許可證之外,此代碼還將發布到Public Domain
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.