Подтвердить что ты не робот

Как принять решение без оператора if

Я беру курс на Java, и мы еще не узнали, что делать. Я изучал и видел этот вопрос:

Напишите метод под названием pay, который принимает два параметра: действительное число для зарплаты TA и целое число для числа часов, которые TA работала на этой неделе. Метод должен вернуть, сколько денег заплатить TA. Например, плата за вызов (5.50, 6) должна вернуть 33.0. ТП должна получать "сверхурочную" плату в 1,5 раза больше обычной зарплаты за любые часы выше 8. Например, должна быть возвращена плата за вызов (4.00, 11) (4.00 * 8) + (6.00 * 3) или 50.0.

Как вы решаете это без использования операторов if? Пока у меня есть это, но я застрял на регулярной оплате:

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

     double pay = 0;

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

Ответ 1

Чтобы избежать прямого использования операторов управления потоком, таких как if или while, вы можете использовать Math.min и Math.max. Для этой конкретной проблемы использование цикла также неэффективно.

Они могут технически использовать операторы if или эквивалент, но так делают многие ваши другие вызовы стандартной библиотеки, которые вы уже делаете:

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));
}

Ответ 2

Поскольку вы использовали цикл 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;
}

Это суммирует зарплату за обычные часы до 8, а затем суммирует зарплату за сверхурочные часы, где сверхурочные часы оплачиваются с зарплатой 1,5 *.

Если часов сверхурочных нет, второй цикл цикла не будет введен и не будет иметь эффекта.

Ответ 3

Есть несколько способов сделать это, но трудно понять, что разрешено (если вы даже не можете использовать if).

Я бы рекомендовал использовать цикл while:

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

Причина этого в том, что это уменьшает ваш hoursWorked до значения, которое гарантировано меньше или равно 8 (при условии, что hoursWorked и salary больше, чем 0). Если hoursWorked <= 8, то он никогда не войдет в цикл while.

Ответ 4

Если вы действительно хотите взломать, вы можете использовать побитовые операторы:

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

return otherHours * 0.5 * salary + hours * salary;

В принципе, если otherHours отрицательно, переплаты не должно быть. Мы делаем это, выбирая знаковый бит otherHours и переставляя его на младший значащий бит (с 0 дополнением), чтобы означать либо 1, либо 0. После первого отрицания (если знаковый бит равен 1, множитель должен быть 0).

Когда вы умножаете это значение на otherHours, оно будет 0 в случае, если осталось менее 8 часов, чтобы не вычитать какую-либо сумму при окончательном вычислении.

Ответ 5

Только для записи, вот решение, очень близкое к тому, где вы были остановлены:

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

Ответ 6

Вы можете просто использовать тернарный оператор ?::

 pay = hours*salary + ((hours > 8) ? (hours-8)*salary*0.5 : 0); 

- выплачивать стандартную зарплату за все время работы, плюс 50% на время свыше 8 часов (если есть).

Ответ 7

Для этой цели можно использовать для int.

Заметим, что функция

f(x) = 10/9 - 1/(x+1) = 1 + 1/9 - 1/(x+1)

находится между 0 и 1 (исключение) для 0 <= x < 8 и между 1 и 1.2 для x >= 8. Отбросив это значение до int результатов 0 для x < 8 и в 1 для x >= 8.

Это можно использовать при вычислении результата:

public static double pay(double salary, int hours) {
    int overtime = (int)(10d/9d - 1d/(hours+1));
    return salary * (hours + 0.5 * overtime * (hours - 8));
}

Ответ 8

Вот способ сделать это с помощью truncation from integer division, что вы, вероятно, узнали в начале курсов java. По существу решение представляет собой один вкладыш, который не нуждается в if, loops, comparisons, libraries.

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

    //Pay all hours as overtime, and then subtract the extra from the first 8 hours
    double p1 = (hours * 1.5 * salary) - (4 * salary); 

    //In the case where the TA works for less than 8 hours, 
    //subtract all the extra so that ultimately, pay = salary * hours
    double p2 = (hours * 0.5 * salary) - (4 * salary); 

    //When theres no overtime worked, m equals to 1. 
    //When there are overtime hours, m is equals to 0.
    int m = (8 + 7) / (hours + 7);

    //When there are overtime hours, pay is simply equal to p1. 
    //When there are no overtime hours, p2 is subtracted from p1.
    return p1 - m*p2; 
}

Ответ 9

Решение, которое не использует никаких условных (неявных или явных)

Практически вам нужно вычислить hours * rate, но если у вас есть сверхурочная работа, вам нужно добавить бонус формы overtime_hours * overtime_rate

в псевдокоде:

//you need to return:
hours * rate + is_overtime * overtime_time * overtime_rate

где

is_overtime = ceiling ( x / (x+1))  # this will be zero when x == 0, in rest 1 
x = integer_division(hours, 8)   # x == 0 if no overtime, in rest a positive integer
overtime_time = hours - 8
overtime_rate = (1.5 - 1) * rate = 0.5 * rate

Ответ 10

(((hours/8)-1)*8 + hours%8)*salary*0.5 + (hours*salary)
                   overtime*salary*0.5 + (hours*salary)

(((   11/8 -1)*8 +    11%8)*     4*0.5 + (   11*     4) = 50
((      1  -1)*8 +       3)*         2 +             44 = 50
((          0)*8 +       3)*         2 +             44 = 50
((             0 +       3)*         2 +             44 = 50
                                     6 +             44 = 50

Итак, предположим, что у нас (17 часов, 4 зарплаты)

(((17/8)-1)*8 + 17%8)*4*0.5 + 17*4 = 86
(    (2 -1)*8 +    1)*4*0.5 +   68 = 86
           (8 +    1)*2     +   68 = 86
                    9*2     +   68 = 86
                     18     +   68 = 86

17-8 = 9 - сверхурочное время

9 * 4 * 1,5 + 8 * 4 = 9 * 6 + 32 = 54 + 32 = 86

Ответ 11

Вы могли бы творчески использовать оператор while как оператор if

while(hours > 8){
  return ((hours - 8) * salary * 1.5) + (8 * salary);
}
return hours * salary;

Ответ 12

Уже много хороших и более эффективных ответов, но здесь есть еще одна простая опция, использующая цикл while и тернарный оператор:

double pay = 0.0;

while(hours > 0){
    pay += hours > 8 ? wage * 1.5 : wage;
    hours--;
}       
return pay;

Ответ 13

Используя tanh, чтобы решить, находятся ли hours ниже 8 или нет:

public static double pay (double salary, int hours) {
    int decider = (int)(tanh(hours - 8) / 2 + 1);

    double overtimeCompensation = 1.5;
    double result = salary * (hours * (1 - decider) + (8 + (hours - 8) * overtimeCompensation) * decider);
    return result;
}

Переменная decider равна 0, когда hours меньше 8, в противном случае 1. Уравнение в основном содержит две части: первая hours * (1 - decider) будет для hours < 8 и (8 + (hours - 8) * overtimeCompensation) * decider для, когда hours >= 8, Если hours < 8, то 1 - decider равно 1 и decider равно 0, поэтому с использованием первой части уравнений. И если hours >= 8, 1 - decider равно 0, а decider равно 1, то происходит обратное, первая часть уравнения равна 0, а вторая умножается на 1.

Ответ 14

публичная статическая двойная зарплата (двойная зарплата, в часах) {

    int extra_hours = hours - 8;
    extra_hours = extra_hours > 0 ? extra_hours : 0;


    double extra_salary = (salary * 1.5) * extra_hours;
    double normal_salary = extra_hours > 0 ? salary * 8 : salary * hours;

    return normal_salary + extra_salary;
}

Ответ 15

Вы можете использовать троичный оператор.

public static double pay(double salary, int hours){ //get the salary and hours return hours>8?(1.5*hours-4)*salary:hours*salary; }

Ответ 16

Некоторые языки программирования имеют явные функции сопоставления шаблонов. Так, например, в XSLT данный шаблон будет срабатывать, если обработанная node будет соответствовать заданному запросу XPATH лучше, чем другие шаблоны в вашей программе.

Такое "декларативное" программирование является уровнем абстракции выше, чем у вас на Java, но у вас все еще есть switch который дает вам возможность управлять потоком с помощью "совпадающего" подхода, а не с использованием явных конструкций if-else.

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

 double pay = 0;

 for (int i = hours; i > 0;i--){ 
     switch (i){
         case 1:
         case 2:
         case 3: 
         case 4: 
         case 5:
         case 6:
         case 7:            
            pay += (salary);
            break;
         default:
            pay += (salary * 1.5);
            break;
     }
 }
 return pay;
}

Сказав, что для вашего конкретного примера то, что вам действительно нужно, это оператор if. Подход switch будет работать, но он немного надуман.

Ответ 17

В Tsql

DECLARE @amount float = 4.00 , @hrs int = 11

DECLARE @overtime int , бит @overeight

SET @overeight = ((@hrs/8) ^ 1)

SET @overtime = ПОТОЛОК ((@hrs% 8)/((@hrs% 8) + 1.0)) * ~ @overeight

- SELECT @hrs * @amount

SELECT ((@hrs - (@hrs% 8 * ~ @overeight)) * @amount) + (@overtime * (@hrs% 8 * (@amount * 1.5)))

(от Валентина выше)