Учебные задачи PHP. Задача 6

Дано некоторое число длиной от 1 до 5 символов, вывести все его "нечётные" цифры в обратном порядке (аналогично предыдущей задаче), если же таких цифр не найдёт, вывести сообщение "Нечетных цифр не обнаружено!"

Решение задачи с четными цифрами:

<?php
function outputNumberInReverseOrder($number)
{
    echo $number, " = <br>";
	$arr = array();
    while ($number >= 1) {		
        $remainderOfDivision =  $number % 10;
		if ($remainderOfDivision % 2 == 1) {
			$arr[] = $remainderOfDivision;
		}
		if ($remainderOfDivision % 2 == 1) {
			echo $remainderOfDivision, "<br>";
		}
        $numberDividedBy10 = $number / 10;        
        $number = $numberDividedBy10;
        }
	if ($arr === []) {
		echo "Нечетных цифр не обнаружено! <br>";
	}
}
outputNumberInReverseOrder(2468);
?>

Решение задачи с нечетными цифрами:

<?php
function outputNumberInReverseOrder($number)
{
    echo $number, " = <br>";
	$arr = array();
    while ($number >= 1) {		
        $remainderOfDivision =  $number % 10;
		if ($remainderOfDivision % 2 == 1) {
			$arr[] = $remainderOfDivision;
		}
		if ($remainderOfDivision % 2 == 1) {
			echo $remainderOfDivision, "<br>";
		}
        $numberDividedBy10 = $number / 10;        
        $number = $numberDividedBy10;
        }
	if ($arr === []) {
		echo "Нечетных цифр не обнаружено! <br>";
	}
}
outputNumberInReverseOrder(1357);
?>

Key Words for FKN + antitotal forum (CS VSU):

melisa's picture

  1. Решение задачи с четными цифрами

    Не поняла смысла. Вроде оба варианта решения одинаковы)

  2. $numberDividedBy10

    Некорректное имя переменной. Оно не должно содержать цифр.

  3.         if ($remainderOfDivision % 2 == 1) {
                $arr[] = $remainderOfDivision;
            }
            if ($remainderOfDivision % 2 == 1) {
                echo $remainderOfDivision, "<br>";
            }

    Не нужно запрашивать условие для каждой операции, можно написать в теле одного if оба действия

  4. $arr = array();

    В современный версиях php используется укороченная запись:

    $arr = [];
  5. if ($arr === [])

    Вместо оператора сравнения воспользуйтесь встроенной функцией php, empty()

Вместо оператора сравнения воспользуйтесь встроенной функцией php, empty()

Да, спасибо. На просторах инета видел этот вариант. Но один товарищ сказал:

if($array === []){ ... }

Более оптимальный так как:
- Код более читаемый - "Если переменная равна пустому массиву";
- Сразу идет контроль типов, и вы действительно сравниваете массив;
- Не используются функции, а только сравнение, значит этот код будет работать немного быстрее;

Что тоже мне показалось интересным.

melisa's picture

Целесообразность разных способов, конечно, нужно рассматривать в каждом конкретном случае. В данном я предложила использовать функцию с целью ознакомления с альтернативным вариантом.

Несколько расширил условия задачи с дополнительными выводами.

<?php
function outNumbInRevOrd($number)
{
    $remOfDivArrOdd = [];
    $remOfDivArrEven = [];
     
    while ($number >= 1) {      
        $remOfDiv = $number % 10;      
        if ($remOfDiv % 2 == 1) {
            $remOfDivArrOdd[] = $remOfDiv;  // массив НЕчетных цифр
        } else {
            $remOfDivArrEven[] = $remOfDiv; // массив ЧЕтных цифр
        }
        $number = $number / 10;   // в/о остаток от деления нужно вычесть из числа?
    }
 
    if ((!($remOfDivArrOdd == [])) && (!($remOfDivArrEven == []))) { 
        echo "НЕчетные и ЧЕтные присутствуют! <p>"; 
        return $remOfDivArrOdd;
    }
     
    if (!($remOfDivArrOdd == [])) { // если массив не пуст
        echo "Четных цифр не обнаружено! <p>"; 
        return $remOfDivArrOdd;       
    }
     
    if (!($remOfDivArrEven == [])) {    // если массив не пуст
        echo "Нечетных цифр не обнаружено! <p>"; 
        return $remOfDivArrOdd;
    }       
}
$number = 234;                  
$output = outNumbInRevOrd($number); 
echo "$number = <br>";               
foreach ($output as $value) {   
    echo $value. '<br>';
}
?>
melisa's picture

  1. if ((!($remOfDivArrOdd == [])) && (!($remOfDivArrEven == []))) { 
            echo "НЕчетные и ЧЕтные присутствуют! <p>"; 
            return $remOfDivArrOdd;
        }
          
        if (!($remOfDivArrOdd == [])) { // если массив не пуст
            echo "Четных цифр не обнаружено! <p>"; 
            return $remOfDivArrOdd;       
        }
          
        if (!($remOfDivArrEven == [])) {    // если массив не пуст
            echo "Нечетных цифр не обнаружено! <p>"; 
            return $remOfDivArrOdd;
        }       

    Всю эту конструкцию можно написать короче с помощью оператора elseif

  2. return $remOfDivArrOdd;

    Неверно эту строку писать внутри условий, т.к. условия никак на неё не влияют. и от них она не зависит. тем более трижды.

  3. !($remOfDivArrEven == [])

    Для отрицания равенства существуют свои операторы сравнения.

Всю эту конструкцию можно написать короче с помощью оператора elseif

Для отрицания равенства существуют свои операторы сравнения

Спасибо. Переделал.

Насчет этого момента:

Неверно эту строку писать внутри условий, т.к. условия никак на неё не влияют. и от них она не зависит. тем более трижды.

Я, возможно, где-то здесь недопонимаю, но, в тестовом режиме, я подставлял поочередно два массива (для четных и нечетных цифр) и видел, как это условие:

return $remOfDivArrOdd;

или

return $remOfDivArrEven;

влияло на результат, т.е. выводило либо четные, либо нечетные цифры.
Другой момент, когда я ставил подряд два эти условия:

if (($remOfDivArrOdd != []) && ($remOfDivArrEven != [])) { 
        echo "НЕчетные и ЧЕтные присутствуют! <p>"; 
		return $remOfDivArrOdd;
		return $remOfDivArrEven;

то выполнялось только первое условие по ходу движения.

Строка 25. Я поставил

return $remOfDivArrEven;

что против условия задачи (выводить в обр порядке НЕчетные цифры), код стал выводить ЧЕтные цифры в обр порядке, как в этом примере:

<?php
function outNumbInRevOrd($number)
{
    $remOfDivArrOdd = [];
    $remOfDivArrEven = [];
      
    while ($number >= 1) {      
        $remOfDiv = $number % 10;      
        if ($remOfDiv % 2 == 1) {
            $remOfDivArrOdd[] = $remOfDiv;  // массив НЕчетных цифр
        } else {
            $remOfDivArrEven[] = $remOfDiv; // массив ЧЕтных цифр
        }
        $number = $number / 10;   
    }

    if (($remOfDivArrOdd != []) && ($remOfDivArrEven != [])) { 
        echo "НЕчетные и ЧЕтные цифры присутствуют! <p>"; 
		return $remOfDivArrOdd;
    } elseif ($remOfDivArrOdd != []) { 
        echo "Четных цифр не обнаружено! <p>"; 
        return $remOfDivArrOdd;       
	} elseif ($remOfDivArrEven != []) {    
        echo "Нечетных цифр не обнаружено! <p>"; 
        return $remOfDivArrEven;
    }       
}
$number = 246;                  
$output = outNumbInRevOrd($number); 
echo "$number = <br>";               
foreach ($output as $value) {   
    echo $value. '<br>';
}
?>
melisa's picture

  1. Во-первых

    Насчет этого момента:

    Неверно эту строку писать внутри условий, т.к. условия никак на неё не влияют. и от них она не зависит. тем более трижды.

    Я, возможно, где-то здесь недопонимаю, но, в тестовом режиме, я подставлял поочередно два массива (для четных и нечетных цифр) и видел, как это условие:

    return $remOfDivArrOdd;

    или

    return $remOfDivArrEven;

    влияло на результат, т.е. выводило либо четные, либо нечетные цифры.

    в задаче просили выводить только нечётные цифры или текст в случае их отсутствия. Я не против, если Вы сделали немного бОльшую работу, однако у нас из-за этого возникли дополнительные трудности.

    Так вот, естественно, что если Вы возвращаете две разных переменных, результат меняется. Но в Вашем коде Вы возвращаете одну и ту же переменную 3 раза. Это избыточный код, да ещё и не в том месте.

    Условия elseif влияют только на текст, который Вы печатаете с помощью echo прямо внутри функции. На возвращаемое значение условия НИКАК не влияют, а значит, не надо его возвращать внутри условий (тем более внутри каждого условия), а возвращайте ниже.

    if ((!($remOfDivArrOdd == [])) && (!($remOfDivArrEven == []))) { 
            echo "НЕчетные и ЧЕтные присутствуют! <p>"; 
            return $remOfDivArrOdd;
        }
           
        if (!($remOfDivArrOdd == [])) { // если массив не пуст
            echo "Четных цифр не обнаружено! <p>"; 
            return $remOfDivArrOdd;       
        }
           
        if (!($remOfDivArrEven == [])) {    // если массив не пуст
            echo "Нечетных цифр не обнаружено! <p>"; 
            return $remOfDivArrOdd;
        }

    Возвращается при любом тексте одно и то же значение. Видите?

  2. Во-вторых

    Другой момент, когда я ставил подряд два эти условия:

    if (($remOfDivArrOdd != []) && ($remOfDivArrEven != [])) { 
            echo "НЕчетные и ЧЕтные присутствуют! <p>"; 
            return $remOfDivArrOdd;
            return $remOfDivArrEven;

    то выполнялось только первое условие по ходу движения.

    По этому комментарию видно, что Вы так и не поняли смысла возврата значения функцией. Как только функция натыкается на команду return, она прекращает дальнейшее чтение кода и выводит наружу результат. Всё, что ниже не будет прочитано никогда.

  3. В-третьих,
    return $remOfDivArrEven;

    В последнем варианте решения Вы уже и чётные выводите, что прямо противоречит условию. Давайте лучше, будем поступательно двигаться и дайте сначала результат чётко соответствующий запросу задачи.

<?php
function outNumbInRevOrd($number)
{
    $remOfDivArrOdd = [];	// массив НЕчетных цифр
    $remOfDivArrEven = [];	// массив ЧЕтных цифр
       
    while ($number >= 1) {      
        $remOfDiv = $number % 10;      
        if ($remOfDiv % 2 == 1) {
            $remOfDivArrOdd[] = $remOfDiv;  // массив НЕчетных цифр
        } else {
            $remOfDivArrEven[] = $remOfDiv; // массив ЧЕтных цифр
        }
        $number = $number / 10;   
	}
	if ($remOfDivArrOdd == []) { 
			echo "Нечетных цифр не обнаружено! <p>"; 
    }
	return $remOfDivArrOdd;
}
$number = 12345;                  
$output = outNumbInRevOrd($number); 
echo "$number = <br>"; 

foreach ($output as $value) {   
    echo $value. '<br>';
}
?>
melisa's picture

$remOfDivArrEven = [];  // массив ЧЕтных цифр

это избыточный код

else {
    $remOfDivArrEven[] = $remOfDiv; // массив ЧЕтных цифр
}

это тоже

<?php
function outNumbInRevOrd($number)
{
    while ($number >= 1) {      
        $remOfDiv = $number % 10;      
        if ($remOfDiv % 2 == 1) {
            $remOfDivArrOdd[] = $remOfDiv;  // массив НЕчетных цифр
        }
        $number = $number / 10;   
    }
    if ($remOfDivArrOdd == []) { 
            echo "Нечетных цифр не обнаружено! <p>"; 
    }
    return $remOfDivArrOdd;
}
$number = 468;                  
$output = outNumbInRevOrd($number); 
echo "$number = <br>"; 
 
foreach ($output as $value) {   
    echo $value. '<br>';
}
?>
melisa's picture

предупреждений быть не должно

E_NOTICE : type 8 -- Undefined variable: remOfDivArrOdd -- at line 11
Нечетных цифр не обнаружено!

E_NOTICE : type 8 -- Undefined variable: remOfDivArrOdd -- at line 14
468 =

E_WARNING : type 2 -- Invalid argument supplied for foreach() -- at line 20

Странно, при первом запуске не было этой записи, хотя я ее ожидал. При втором запуске - она появилась.
ИСПРАВИЛ.

<?php
function outNumbInRevOrd($number)
{
	$remOfDivArrOdd = [];
	
    while ($number >= 1) {      
        $remOfDiv = $number % 10;      
        if ($remOfDiv % 2 == 1) {
            $remOfDivArrOdd[] = $remOfDiv;  // массив НЕчетных цифр
        }
        $number = $number / 10;   
    }
    if ($remOfDivArrOdd == []) { 
            echo "Нечетных цифр не обнаружено! <p>"; 
    }
    return $remOfDivArrOdd;
}
$number = 4682468;                  
$output = outNumbInRevOrd($number); 
echo "$number = <br>"; 
 
foreach ($output as $value) {   
    echo $value. '<br>';
}
?>
melisa's picture

принято