34 votes

Comment prendre une décision sans instruction "si" ?

Je suis un cours de Java et nous n'avons pas encore officiellement appris les instructions if. En étudiant, j'ai vu cette question :

Écrivez une méthode appelée pay qui accepte deux paramètres : un nombre réel pour le salaire d'un TA, et un nombre entier pour le nombre d'heures que le TA a travaillé cette semaine. La méthode doit retourner le montant à payer au TA. Par exemple, l'appel pay(5,50, 6) devrait donner 33,0. Le TA doit recevoir une rémunération pour "heures supplémentaires" égale à 1,5 fois le salaire normal pour toutes les heures au-delà de 8. Par exemple, l'appel paye(4.00, 11) devrait donner (4.00 * 8) + (6.00 * 3) ou 50.0.

Comment résoudre ce problème sans utiliser les instructions if ? Pour l'instant, j'ai réussi, mais je suis bloqué sur la rémunération régulière :

public static double pay (double salary, int hours) {

     double pay = 0;

     for (int i = hours; i > 8; i --) {
         pay += (salary * 1.5);
     }
}

12 votes

Si vous avez déjà appris les boucles mais pas les déclarations if (ce qui est bizarre d'ailleurs) vous pouvez utiliser for(; condition; ) { …; break; } comme if (condition) { … }

6 votes

@Bergi : c'est vrai, si c'est censé être une énigme où le questionneur a les mains liées, alors c'est une bonne façon de les délier en respectant les règles. Si ce n'est pas censé être ce genre d'énigme, alors sans savoir ce qu'il faut faire a J'ai un peu de mal à comprendre la réponse attendue par le professeur de l'auteur de la question. J'espère que no que. Il y a quelques bonnes suppositions dans les réponses :-)

1 votes

Je ne comprends pas bien pourquoi on s'agite autour du fait de ne pas utiliser une if déclaration. Je vois la question et je me dis : pourquoi utiliser une if mais cela ne fait que rendre mon code plus long/plus compliqué. Lorsque j'utilise if Je dois effectivement recréer min y max . Ce type de calcul est ce que min y max sont destinés. Dans de nombreuses situations (par exemple, une feuille de calcul), ils sont définitivement la solution préférée.

82voto

NESPowerGlove Points 2633

Pour éviter l'utilisation directe de déclarations de contrôle de flux comme if o while vous pouvez utiliser Math.min y Math.max . Pour ce problème particulier, l'utilisation d'une boucle ne serait pas non plus efficace.

Ils peuvent techniquement utiliser des instructions if ou l'équivalent, mais il en va de même pour beaucoup d'autres appels à la bibliothèque standard que vous faites déjà :

public static double pay (double salary, int hours) {
     int hoursWorkedRegularTime = Math.min(8, hours);
     int hoursWorkedOverTime = Math.max(0, hours - 8);
     return (hoursWorkedRegularTime * salary) +
            (hoursWorkedOverTime  * (salary * 1.5));
}

1 votes

J'aime bien celui-là. Pas de comparaisons du tout.

9 votes

@zero298 Sauf min y max utilisent des opérateurs ternaires, qui effectuent une comparaison.

1 votes

@JornVernee Mais c'est sous le capot. Il n'y a pas de comparaisons dans ce bout de source.

54voto

js441 Points 1131

Puisque vous avez utilisé une boucle for, voici une solution qui consiste à utiliser deux boucles for.

public static double pay (double salary, int hours) {

    double pay = 0;

    for (int i = 0; i < hours && i < 8; i++) {
        pay += salary;
    }
    for (int i = 8; i < hours; i++) {
        pay += (salary * 1.5);
    }

    return pay;
}

Il s'agit d'additionner le salaire pour les heures normales jusqu'à 8, puis le salaire pour les heures supplémentaires, ces dernières étant payées à 1,5 * salaire.

S'il n'y a pas d'heures supplémentaires, la deuxième boucle for ne sera pas saisie et n'aura aucun effet.

1 votes

Peut-être i < hours && i < 8 dans la première boucle et salary * 1.5 dans le second serait plus clair.

17 votes

Je pense que c'est en fait la réponse que le professeur cherche, bien que je pense que la logique du professeur est plutôt stupide parce que toutes les boucles utilisent une sorte d'instruction de branchement afin de sortir d'une boucle.

1 votes

@rabbitguy Je ne pense pas que le professeur ait défini "ne pas utiliser les instructions if" comme une exigence. La question dit simplement "nous n'avons pas encore officiellement appris les instructions if".

20voto

ihgann Points 490

Il y a plusieurs façons de procéder, mais il est difficile de savoir ce qui est autorisé (si vous ne pouvez même pas utiliser la fonction if ).

Je recommande d'utiliser un while boucle :

double pay = 0;
while (hoursWorked > 8) {
    pay += (salary * 1.5);
    hoursWorked--;
}
pay += (hoursWorked * salary);

La raison pour laquelle cela fonctionne est que cela décrémente votre hoursWorked à une valeur qui est garantie comme étant inférieure ou égale à 8 (en supposant que hoursWorked y salary sont toutes deux supérieures à 0 ). Si hoursWorked <= 8 alors il n'entrera jamais dans le while boucle.

1 votes

A while La boucle est essentiellement une instruction if, mais avec un saut en arrière à la fin. Vous pourriez aussi le faire : int otherHours = hoursWorked - 8; while(otherHours > 0) { pay += otherHours * salary * 1.5; break; } ...

2 votes

Tout est essentiellement du sucre syntaxique pour if dans ces réponses. Il n'y a pas une correct mais ce type de questions vise simplement à vous inciter à être créatif avec d'autres approches.

1 votes

Je n'essayais pas de critiquer, je ne faisais que compléter la réponse ;).

20voto

Jorn Vernee Points 18630

Si vous voulez vraiment faire du bricolage, vous pouvez utiliser des opérateurs binaires :

int otherHours = hours - 8;
int multiplier = (~otherHours & 0x80000000) >>> 31;
otherHours *= multiplier;

return otherHours * 0.5 * salary + hours * salary;

Donc, en gros, si otherHours est négatif, il ne devrait pas y avoir de surpaiement. Pour ce faire, nous sélectionnons le bit de signe de otherHours et le décale vers le bit le moins significatif (avec un remplissage de 0) pour signifier soit 1 soit 0. Après l'avoir d'abord nié (si le bit de signe est 1, le multiplicateur doit être 0).

Quand vous multipliez cela avec otherHours il sera 0 dans le cas où il y a moins de 8 heures, afin de ne pas soustraire accidentellement une rémunération, lors du calcul final.

16 votes

J'ai l'impression que si le PO ne peut pas utiliser les instructions if, le professeur pourrait être un peu suspicieux si l'étudiant devient soudainement un magicien du décalage :)

6voto

fxm Points 2473

Pour mémoire, voici une solution assez proche de l'endroit où vous avez été arrêté :

public static double pay (double salary, int hours) {
     double pay = salary * hours;
     for (int i = hours; i > 8; i --) {
         pay += salary * 0.5;
     }
}

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