3 votes

Comment faire en sorte qu'une instruction conditionnelle renvoie vrai lorsqu'une seule condition est vraie ?

Je dois faire une instruction if dans laquelle sa valeur dépend de N autres conditions. En particulier, elle doit retourner vrai seulement quand une des N conditions est vraie (si plus d'une condition est vraie, elle doit retourner faux). Plus formellement, if (1, 2, 3 ... N) doit évaluer vrai si et seulement si une seule des déclarations est vraie sinon, il évalue faux.

J'ai mis en œuvre cette méthode,

boolean trueOnce(boolean[] conditions) {

    boolean trueOnce = false;

    for (boolean condition : conditions) {
        if (condition) {
            if (!trueOnce) {
                trueOnce = true;
            } else {
                trueOnce = false;
                break;
            }
        }
    }

    return trueOnce;
}

mais je demande quelque chose de plus pratique. Je travaille avec Java, mais je pense que ce problème est universel pour tous les langages. Merci.

EDIT : cette méthode fait très bien l'affaire, mais ma question est la suivante : est-ce que Java (ou tout autre langage) a une façon plus pratique de faire cela (c'est-à-dire sans même implémenter une méthode entière) ?

3voto

Nikolas Points 11342

Une simple boucle avec une condition comptant les true La présence est un moyen simple de procéder L'instruction de retour est une comparaison renvoyant un boolean si le true count est exactement égal à 1 :

long count = 0;
for (boolean condition: conditions) {
    if (condition) {
        count++;
    }
}
return count == 1;

Cela fait toujours itérer tout le tableau, ce qui n'est pas toujours nécessaire. Vous pouvez optimiser l'itération pour qu'elle s'arrête lorsqu'il y a deux objets true valeurs trouvées, donc cela n'a pas de sens de continuer l'itération.

long count = 0;
for (boolean condition: conditions) {
    if (condition && ++count > 1) {
        break;
    }
}
return count == 1;

3voto

RIVERMAN2010 Points 343

Vous pouvez utiliser cette solution

public boolean trueOnce(boolean[] conditions) {
         boolean m = false;
         for(boolean condition : conditions) {
             if(m && condition)
                 return false;
             m |= condition;
         }
         return m;
     }

Il s'agit d'une toute petite solution qui fait exactement ce que vous voulez en très peu de lignes.

3voto

vlaz Points 4038

Utilisation de l'API Java Stream :

boolean trueOnce(boolean[] conditions) {
    return IntStream.range(0, conditions.length)
        .filter(x -> conditions[x])  // leave only `true` values
        .limit(2)             // no need to get more than two
        .count() == 1;        // check if there is only one `true` value
}

0voto

Alex Rudenko Points 15648

En utilisant l'API Stream, vous pourriez le réécrire comme (bien que cela semble moins "pratique" qu'une simple boucle) :

import java.util.stream.*;

static boolean trueOnce(boolean ... conditions) {
    // find index of first true, if not available get -1
    int firstTrue = IntStream.range(0, conditions.length)
                             .filter(i -> conditions[i])
                             .findFirst().orElse(-1);

    // if first true is found, check if none in the remainder of array is true
    return firstTrue > -1 && IntStream.range(firstTrue + 1, conditions.length)
                                      .noneMatch(i -> conditions[i]);
}

Restauration de la version initiale avec un changement suggéré par @VLAZ :

import java.util.stream.*;

boolean trueOnce(boolean[] conditions) {
    return IntStream.range(0, conditions.length)
                    .filter(i -> conditions[i])
                    .limit(2) // !
                    .count() == 1;
}

0voto

Une itération peut être effectuée à l'aide de l'opérateur while. Une variable est définie pour contrôler les incréments des valeurs positives et une autre pour évaluer chaque élément du tableau. Ces deux variables seront nos conditions d'arrêt et la méthode renverra la solution, vraie lorsqu'il y a une seule valeur positive et fausse dans tous les autres cas.

boolean trueOnce(boolean[] conditions) 
    {
        int i = 0, count = 0;

        while(count <= 1 && i < conditions.length){
            if(conditions[i++]){
                count++;
            }
        }

        return count == 1;
    }

ou en suivant la suggestion, nous pouvons utiliser :

private static boolean trueOnce(boolean[] conditions) 
{
    int count = 0;

    for(int i = 0; i < conditions.length && count <= 1; i++){
        if(conditions[i]){
            count++;
        }
    }

    return count == 1;
}

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