[英]How to shorten multiple && condition
目前我可以運行我的程序,但我的代碼包含很多重復,看起來像:
while(option != 'E' && option != 'D' && option != 'P' && option != 'Q' &&
option != 'e' && option != 'd' && option != 'p' && option != 'q') {
// Some code here
}
要么:
while(cType != 'S' && cType != 'L' && cType != 'O' && cType != 'Q' &&
cType != 's' && cType != 'l' && cType != 'o' && cType != 'q') {
// Some code here
}
縮短上述代碼的最快方法是什么?
(除了使用附加功能有什么辦法嗎?)
const char invalidChars[] = "edpq";
while (strchr(invalidChars, tolower(option)) != 0) {
...
}
您可以初始化包含要匹配的字符的字符串,然后使用find
,如果未find
匹配項,則返回npos
:
string match = "SLOQsloq";
while (match.find(cType) == string::npos)
...
你可以用std::tolower
擺脫一半的條件
while(std::tolower(option) != 'e' && std::tolower(option) != 'd' && std::tolower(option) != 'p' && std::tolower(option) != 'q')
你也可以使用一個std::string
,它的find
成員函數,如:
std::string options = "edpq";
//...
while (options.find(std::tolower(option)) == std::string::npos)
您可以通過使用std::set
並檢查集合是否包含(或不包含)我們要比較的變量來簡化邏輯並使事物更具可讀性:
std::set<char> someChars { 'a', 'b', 'c' };
if(someChars.find(myChar) != someChars.end()) {
// myChar is either 'a', 'b', or 'c'
}
大多數其他語言中的條件將更加干凈地寫成someChars.contains(myChar)
(但C ++的set接口非常小)。
但是,對於少量比較,您的方法可能更快。
沒有分支的候選快速測試。
1)減少無殼。
2)形成4個不同的產品。
3)1與0比較。
只假設字母。
最多可以使用4個( sizeof int/sizeof char
)字母。
大小寫不同的位相同。 (這適用於ASCII和EBCDIC)
#define CaseMaskBits ((unsigned char)~('A'^'a'))
#define Product4(ch, s) ((ch-s[0]) * (ch-s[1]) * (ch-s[2]) * (ch-s[3]))
#define TestEq4(ch, t, s) (t=ch&CaseMaskBits, !Product4(t, s))
int main(void) {
int ch;
printf("%X\n", CaseMaskBits);
for (ch = 0; ch < 256; ch++){
int t; // temp var for TestEQ4
while (TestEq4(ch, t, "ELPQ")) {
printf("%d %c\n", ch, ch);
break;
}
}
return 0;
}
280 while (TestEq4(ch, t, "ELPQ")) {
00402560: mov %ebx,%eax
00402562: and $0xdf,%eax
00402567: lea -0x4c(%eax),%edx
0040256a: lea -0x45(%eax),%ecx
0040256d: imul %edx,%ecx
00402570: lea -0x50(%eax),%edx
00402573: sub $0x51,%eax
00402576: imul %ecx,%edx
00402579: imul %edx,%eax
0040257c: test %eax,%eax
0040257e: jne 0x402555 <main+37>
281 printf("%d %c\n", ch, ch);
如果option/cType
具有<= 8位的重要性,則對於速度,使用表查找。 @DieterLücking
unsigned char Table[UCHAR_MAX + 1] = {
fill per needs };
#define Table_OptionMask 1
#define Table_cTypeMask 2
#define Table_nextMask 4
while (!(Table[(unsigned char)option] & Table_OptionMask)) ...
while (!(Table[(unsigned char)cType] & Table_cTypeMask)) ...
為了更簡單的代碼維護,通過調用Table_Setup()
在代碼啟動時填充表。
static void Table_SetInsensitive(unsigned char *Table, unsigned mask, cnst char *src) {
while (*src) {
Table[toupper((unsigned char) *src)] |= mask;
Table[tolower((unsigned char) *src)] |= mask;
src++;
}
}
void Table_Setup(void) {
memset(Table, 0, sizeof Table);
Table_SetInsensitive(Table, Table_OptionMask, "EDPQ");
Table_SetInsensitive(Table, Table_cTypeMask, "SLOQ");
Table_SetInsensitive(Table, Table_cTypeMask, tbd);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.