C ++ рдореЗрдВ рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдВ

Habr рдкрд░ рдкреЛрд╕реНрдЯ рдкрдврд╝рдирд╛, рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд╡рд╛рд▓ рдкрд░ рдареЛрдХрд░ рдЦрд╛рдИред рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рд╕рдорд╛рдзрд╛рди рд╕реБрдЭрд╛рдП рдЧрдП рдереЗ, рд▓реЗрдХрд┐рди рдлрд╝рдВрдХреНрд╢рди рдХреЙрд▓ рдХреЗ рдУрд╡рд░рд╣реЗрдб рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рд▓реЗрдЦрдХ рдХреЗ рдЕрдиреБрдХреВрд▓ рдХреЛрдИ рдирд╣реАрдВ рдерд╛ред рдФрд░ рдлрд┐рд░ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреНрдпреЛрдВ рдирд╣реАрдВ рдПрдХ рдирд┐рдпрдорд┐рдд рд╕реНрд╡рд┐рдЪ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ , рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рд╕реЗ рдПрдХ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ, рдЬрд┐рд╕реЗ рд╕реНрд╡рд┐рдЪ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд▓реЗрдХрд┐рди рдкреНрд░рд╢реНрди рдХреЗ рд▓реЗрдЦрдХ рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХреЛ рдЕрдзрд┐рдХ рдзреНрдпрд╛рди рд╕реЗ рджреЗрдЦрдиреЗ рдкрд░, рдореБрдЭреЗ рдПрд╣рд╕рд╛рд╕ рд╣реБрдЖ рдХрд┐ рдРрд╕рд╛ рд╡рд┐рдХрд▓реНрдк рдХреЗрд╡рд▓ рдЙрд╕реА рддрд░рд╣ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдиреЗрд╕реНрдЯреЗрдб рд╕реНрд╡рд┐рдЪ рдХреЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрд╡рд╢реНрдпрдХ рдерд╛ред

рдорд╛рди рд▓реЗрдВ рдХрд┐ рджреЛ рдЪрд░ n рдФрд░ m рд╣реИрдВ , рдкреНрд░рддреНрдпреЗрдХ рдХрд╛ рдорд╛рди 0 рд╕реЗ 9 рддрдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдФрд░ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдРрд╕реА рд╕рдВрд░рдЪрдирд╛ рд╣реИ:
switch (n) { case 0: { switch (m) { case 2: case 4: ... break; case 5: ... break; default: ... break; } } break; ... } 

рдЪреВрдБрдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдЪрд░ рдХрд╛ рдореВрд▓реНрдп рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рд░рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд ((n << SHIFT ) + m) рд╣реЛрдиреЗ рджреЗрдВ (рдЬрд╣рд╛рдБ SHIFT = 8)ред
рдФрд░ рдпрд╣рд╛рдВ рд╕рдорд╕реНрдпрд╛ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ: рдпрджрд┐ рджреЛрдиреЛрдВ рдорд╛рдиреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рд╣рдо рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХреЗ рдмрд╛рдж рдПрдХ рд╡рд┐рд╢рд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВрдЧреЗред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рд╣рдо n = 0 рдХрд╣реЗрдВ, рдФрд░ m 2,4,5 рдХреЗ рдмрд░рд╛рдмрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдХреНрдпрд╛ рдХрд░рдирд╛ рд╣реИ? рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХреНрд░рд┐рдпрд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╢реЗрд╖ рд╡рд┐рдХрд▓реНрдкреЛрдВ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдирд╛ рдмрд╣реБрдд рдорд╣рдВрдЧрд╛ рд╣реИ, рдХреНрдпреЛрдВрдХрд┐ рдЙрдирдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреА рд╕реАрдорд╛ 0..9 рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рд╕рдХрддреА рд╣реИред рдпрд╣реА рд╣реИ, рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЖрдкрдХреЛ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реАрдорд╛ рдореЗрдВ рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╣реИрд╢ рдХреЗ рдореВрд▓реНрдп рдХреЛ рдкрдХрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред

рдФрд░ рдлрд┐рд░ рдореИрдВрдиреЗ рд╕реЛрдЪрд╛, рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдЕрдЧрд░ рд╣рдо рдЕрдкрдиреЗ рдЖрдк рдХреЛ рдбрд┐рдлреЙрд▓реНрдЯ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, рдкрд╣рд▓реЗ рд╕рднреА рдЬреЛрдбрд╝реЗ рдПрдо рдФрд░ рдПрди рдХреЗ рд▓рд┐рдП рдорд╛рдорд▓рд╛ рд▓рд┐рдЦреЗрдВ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдХреБрдЫ рдХреНрд░рд┐рдпрд╛рдПрдВ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рдкреИрд░рд╛рдореАрдЯрд░ рдПрди рдХреЗ рд╕рд╛рде рдиреЗрд╕реНрдЯреЗрдб рд╕реНрд╡рд┐рдЪ рдХреА рдШреЛрд╖рдгрд╛ рдХрд░реЗрдВ, рддрд╛рдХрд┐ рд╕рднреА рдЕрдиреНрдп рд╕рдВрдпреЛрдЬрдиреЛрдВ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛред

рддреЛ рдореБрдЭреЗ рдХреНрдпрд╛ рдорд┐рд▓рд╛

рдЗрд╕ рддрд░рд╣ рдХреЗ рдПрдХ рд╕рд╛рдзрд╛рд░рдг рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдПрдХ рдирд┐рдпрдорд┐рдд рдореИрдХреНрд░реЛ рдХреЗ рд╕рд╛рде рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЪреВрдВрдХрд┐ const ++ рдлрд╝рдВрдХреНрд╢рди C ++ 11 рдореЗрдВ рджрд┐рдЦрд╛рдИ рджрд┐рдП, рдЗрд╕рд▓рд┐рдП рдореИрдВрдиреЗ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛:
 constexpr int hash(int n, int m) { return verifyValues(n, m) ? ((n << SHIFT) + m): -1; } 

, verifyValues тАЛтАЛрдпрд╣ рд╕рддреНрдпрд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдлрд╝рдВрдХреНрд╢рди рд╣реИ рдХрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рджрд┐рдП рдЧрдП рд░реЗрдВрдЬ рдореЗрдВ рд╣реИрдВред рдЗрд╕рдХреЗ рд▓рд┐рдП, рд╕реНрдерд┐рд░рд╛рдВрдХ MAX_N, MAX_M рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдпрджрд┐ рдкреИрд░рд╛рдореАрдЯрд░ рдорд╛рдиреНрдп рдирд╣реАрдВ рд╣реИрдВ, рддреЛ -1 рд╡рд╛рдкрд╕ рдЖ рдЬрд╛рдПрдЧрд╛ред

 #define isInBound(min, value, max) ((value >= min) && (value <= max)) constexpr bool verifyValues(int n, int m) { return isInBound(0, n, MAX_N) && isInBound(0, m, MAX_M); } 

рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреЛ рджреЗрдЦрддреЗ рд╣реБрдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЪреЗрдХ рдЬреЛрдбрд╝рдирд╛ рдЕрдЪреНрдЫрд╛ рд╣реЛрдЧрд╛:
 MAX_M < pow(2, SHIFT) 

рдореИрдХреНрд░реЛрдЬрд╝ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреЛрдб рдФрд░ рдЪреЗрдХ рдЫрд┐рдкрд╛рдПрдБ:
 #define SWITCH(n, m) static_assert(MAX_M < pow(2, SHIFT), "shift value is not enough to cover all M values"); \ switch(hash(n, m)) #define CASE(n, m) static_assert(verifyValues(n, m), "N or M value is out of range"); \ case hash(n, m) 

рдпрд╣рд╛рдВ, рд╕реНрд╡рд┐рдЪ рдХрд╛ рдирд┐рд░реНрдзрд╛рд░рдг рдХрд░рддреЗ рд╕рдордп , рд╣рдорд╛рд░реЗ рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рди рдХреА рд╕рдВрдЪрд╛рд▓рди рдХреНрд╖рдорддрд╛ рдХреА рддреБрд░рдВрдд рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рдПрдЧреА, рдФрд░ рдмрд╛рдж рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП , рдпрд╣ рдЬрд╛рдБрдЪ рдХреА рдЬрд╛рдПрдЧреА рдХрд┐ рдЗрд╕рдХреЗ рдЪрд░ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕реАрдорд╛ рдореЗрдВ рд╣реИрдВред

рддреЛ рдкрд╣рд▓реЗ рднрд╛рдЧ рдХреЗ рд╕рд╛рде, рдЕрдм рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдЦрдВрдб рд╣реАред
рдпрд╣рд╛рдВ рдХреЗрд╡рд▓ рдПрдХ рдиреЗрд╕реНрдЯреЗрдб рд╕реНрд╡рд┐рдЪ рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдЬрдм рд╕реЗ рдореИрдВрдиреЗ рдореИрдХреНрд░реЛрдЬрд╝ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛, рдореИрдВ рдЙрд╕рдХреЗ рд▓рд┐рдП рдЗрд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░реВрдВрдЧрд╛:
 #define DEFAULT(n) \ case -1: ASSERT(false); break; \ default: switch(n) { #define DEFAULT_CASE(n) case n #define END_DEFAULT } 

рдЪреВрдВрдХрд┐ рд╣реИрд╢ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╕рдордп, рдлрд╝рдВрдХреНрд╢рди -1 рд╡рд╛рдкрд╕ рдЖ рд╕рдХрддрд╛ рд╣реИ (рдпрджрд┐ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдЧрд▓рдд рддрд░реАрдХреЗ рд╕реЗ рдкрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛), рдХреЗрд╕ -1 рдХреЗ рд▓рд┐рдП рдПрдХ рд╣реИрдВрдбрд▓рд░ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рдерд╛ (рдореЗрд░реЗ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдпрд╣ рд╕рд╛рдорд╛рдиреНрдп ASSERT рд╣реИ)ред

рдирддреАрдЬрддрди, рдореБрдЭреЗ рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдРрд╕рд╛ рд╕реНрд╡рд┐рдЪ рдорд┐рд▓рд╛:
 SWITCH(a, b) { CASE(0, 1): CASE(0, 2): CASE(0, 3): CASE(0, 4): ... break; CASE(5, 3): ... break; DEFAULT(a) DEFAULT_CASE(0): ... break; DEFAULT_CASE(1): ... break; DEFAULT_CASE(2): ... break; DEFAULT_CASE(3): ... break; DEFAULT_CASE(4): ... break; DEFAULT_CASE(5): ... break; DEFAULT_CASE(6): ... break; DEFAULT_CASE(7): ... break; DEFAULT_CASE(8): ... break; DEFAULT_CASE(9): ... break; END_DEFAULT } 

рдпрд╣рд╛рдВ рдореБрдЦреНрдп рдмрд╛рдд рдпрд╣ рдирд╣реАрдВ рднреВрд▓рдирд╛ рд╣реИ рдХрд┐ DEFAULT рдореИрдХреНрд░реЛ рдХреЗ рдмрд╛рдж рдЖрдкрдХреЛ рдПрдХ рдХреЛрд▓реЛрди рдбрд╛рд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИред

рдкреВрд░рд╛ рдХреЛрдб
 const int MAX_N = 10; const int MAX_M = 10; const int SHIFT = 8; #define isInBound(min, value, max) ((value >= min) && (value <= max)) constexpr bool verifyValues(int n, int m) { return isInBound(0, n, MAX_N) && isInBound(0, m, MAX_M); } constexpr int hash(int n, int m) { return verifyValues(n, m) ? ((n << SHIFT) + m): -1; } #define SWITCH(n, m) static_assert(MAX_M < pow(2, SHIFT), "shift value is not enough to cover all M values"); \ switch(hash(n, m)) #define CASE(n, m) static_assert(verifyValues(n, m), "N or M value is out of range"); \ case hash(n, m) #define DEFAULT(n) \ case -1: Q_ASSERT(false); break; \ default: switch(n) { #define DEFAULT_CASE(n) case n #define END_DEFAULT } ... SWITCH(a, b) { CASE(0, 1): CASE(0, 2): CASE(0, 3): CASE(0, 4): printf("0, 1-4\n"); break; CASE(5, 3): printf("5, 3\n"); break; DEFAULT(a) DEFAULT_CASE(0): printf("0\n"); break; DEFAULT_CASE(1): printf("1\n"); break; DEFAULT_CASE(2): printf("2\n"); break; DEFAULT_CASE(3): printf("3\n"); break; DEFAULT_CASE(4): printf("4\n"); break; DEFAULT_CASE(5): printf("5\n"); break; DEFAULT_CASE(6): printf("6\n"); break; DEFAULT_CASE(7): printf("7\n"); break; DEFAULT_CASE(8): printf("8\n"); break; DEFAULT_CASE(9): printf("9\n"); break; END_DEFAULT } 


рдирддреАрдЬрддрди, рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕реНрд╡рд┐рдЪ рд╣реИ рдЬреЛ рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдУрд╡рд░рд╣реЗрдб рдХреА, рдПрдХ рдкреНрд░рд╛рдердорд┐рдХ рд╣реИрд╢ рдлрд╝рдВрдХреНрд╢рдиред рд▓реЗрдХрд┐рди рдПрдХ рд╣реА рд╕рдордп рдореЗрдВ, рдорд╛рдорд▓реЗ рдХреЗ рд▓рд┐рдП, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рджреЛрдиреЛрдВ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд╕рдВрдХреНрд░рдордг рдкрд╣рд▓реЗ рд╕реНрд╡рд┐рдЪ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рджреВрд╕рд░реЗ рдореЗрдВ рдкрд╣рд▓реЗ рдХреА рддрд░рд╣ред

рдореБрдЭреЗ рдЙрдореНрдореАрдж рд╣реИ рдХрд┐ рдпрд╣ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХрд┐рд╕реА рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реИред рдЖрдкрдХрд╛ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдзрдиреНрдпрд╡рд╛рджред

PS рд╕рд┐рджреНрдзрд╛рдВрдд рд░реВрдк рдореЗрдВ, рдРрд╕реА рд╕рдВрд░рдЪрдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ, рдЖрдк рди рдХреЗрд╡рд▓ рджреЛ рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд▓рд┐рдП рд╕реНрд╡рд┐рдЪ рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВ, рдмрд▓реНрдХрд┐ рддреАрди рдпрд╛ рдЕрдзрд┐рдХ рдХреЗ рд▓рд┐рдП рднреАред

Source: https://habr.com/ru/post/In183332/


All Articles