119 votes

Comment améliorer la logique pour vérifier si 4 valeurs booléennes correspondent à certains cas

J'ai quatre valeurs bool

 bool bValue1;
bool bValue2;
bool bValue3;
bool bValue4;

Les valeurs acceptables sont:

          Scenario 1 | Scenario 2 | Scenario 3
bValue1: true       | true       | true
bValue2: true       | true       | false
bValue3: true       | true       | false
bValue4: true       | false      | false

Ainsi, par exemple, ce scénario n'est pas acceptable:

 bValue1: false
bValue2: true
bValue3: true
bValue4: true

Pour le moment, j'ai mis au point cette if pour détecter les mauvais scénarios:

 if(((bValue4 && (!bValue3 || !bValue2 || !bValue1)) ||
   ((bValue3 && (!bValue2 || !bValue1)) ||
   (bValue2 && !bValue1) ||
   (!bValue1 && !bValue2 && !bValue3 && !bValue4))
{
    // There is some error
}

Cette logique de déclaration peut-elle être améliorée / simplifiée?

58voto

Zdeslav Vojkovic Points 8911

La vraie question ici est: que se passe-t-il lorsqu'un autre développeur (ou même auteur) doit changer ce code quelques mois plus tard.

Je suggérerais de modéliser cela sous forme d'indicateurs de bits:

 const int SCENARIO_1 = 0x0F; // 0b1111 if using c++14
const int SCENARIO_2 = 0x0E; // 0b1110
const int SCENARIO_3 = 0x08; // 0b1000

bool bValue1 = true;
bool bValue2 = false;
bool bValue3 = false;
bool bValue4 = false;

// boolean -> int conversion is covered by standard and produces 0/1
int scenario = bValue1 << 3 | bValue2 << 2 | bValue3 << 1 | bValue4;
bool match = scenario == SCENARIO_1 || scenario == SCENARIO_2 || scenario == SCENARIO_3;
std::cout << (match ? "ok" : "error");

S'il y a beaucoup plus de scénarios ou plus d'indicateurs, une approche de table est plus lisible et extensible que l'utilisation d'indicateurs. La prise en charge d'un nouveau scénario ne nécessite qu'une autre ligne dans le tableau.

 int scenarios[3][4] = {
    {true, true, true, true},
    {true, true, true, false},
    {true, false, false, false},
};

int main()
{
  bool bValue1 = true;
  bool bValue2 = false;
  bool bValue3 = true;
  bool bValue4 = true;
  bool match = false;

  // depending on compiler, prefer std::size()/_countof instead of magic value of 4
  for (int i = 0; i < 4 && !match; ++i) {
    auto current = scenarios[i];
    match = bValue1 == current[0] && 
            bValue2 == current[1] && 
            bValue3 == current[2] && 
            bValue4 == current[3];
  }

  std::cout << (match ? "ok" : "error");
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X