簡體   English   中英

如何縮短多重&&條件

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM