Задача №12. Заполнение масссивов, сравнение элементов

Даны два массива по 20 элементов каждый (заполните случайными числами, так чтобы среди элементов массива при очередном запуске программы могли встретиться и отрицательные и положительные числа).
Сравните каждый 3-ий элемент 1-ого массива с каждым 2-ым элементом 2-ого массива - сравнение проводите пока не закончится та выборка, которая короче.
Задача отсюда.

<?php
function rand_array($chislo)
{
    for($i = 0; $i < $chislo; $i++) {
       $mas[$i] = rand(-30, 15);
    }
    return $mas;
}

function poluchaem_znachenie($arr)
{
    foreach($arr as $v) {
           echo ' | ', $v, ' | ';
    }
    echo "<br>";
}

function sravnenie_m1_vs_m2($mama, $papa, $doch, $sin)
{
    
    while($doch < count($mama) && $sin < count($papa) ) {
        if($mama[$doch] > $papa[$sin]) {
          echo $mama[$doch], " bolshe ",  $papa[$sin], "<br>";
        }
        elseif($mama[$doch] < $papa[$sin]) {
              echo $mama[$doch], " menshe ",  $papa[$sin], "<br>";
        }
        elseif($mama[$doch] == $papa[$sin]) {
              echo $mama[$doch], " ravno ",  $papa[$sin], "<br>";
        }
        $doch += 3;
        $sin += 2;
    }
}

$n = 20;
$m1 = rand_array($n);
$m2 = rand_array($n);
poluchaem_znachenie($m1);
poluchaem_znachenie($m2);
sravnenie_m1_vs_m2($m1, $m2, 2, 1);
?>

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

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

<?php
function rand_array($chislo)
{
    for($i = 0; $i < $chislo; $i++) {
       $mas[$i] = rand(-30, 15);
    }
    return $mas;
}
 
function poluchaem_znachenie($arr)
{
    foreach($arr as $v) {
           echo ' | ', $v, ' | ';
    }
    echo "<br>";
}
 
function sravnenie_m1_vs_m2($mama, $papa, $doch, $sin)
{
    $m = $doch-1;
    $n = $sin-1;

    while($m < count($mama) && $n < count($papa) ) {
        if ($mama[$m] > $papa[$n]) {
            echo $mama[$m], " bolshe ",  $papa[$n], "<br>";
        } elseif($mama[$m] < $papa[$n]) {
            echo $mama[$m], " menshe ",  $papa[$n], "<br>";
        } else {
            echo $mama[$m], " ravno ",  $papa[$n], "<br>";
        }
        $m += $doch;
        $n += $sin;
    }
}
 
$t = 20;
$m1 = rand_array($t);
$m2 = rand_array($t);
poluchaem_znachenie($m1);
poluchaem_znachenie($m2);
$m = 4; // Каждый m-ый элемент из массива $m1
$n = 2; // И каждый n-ый элемент из массива $m2
sravnenie_m1_vs_m2($m1, $m2, $m, $n);
?>
sid's picture

Спасибо и еще одна проверка на равенство лишняя была.

vedro-compota's picture

function sravnenie_m1_vs_m2($mama, $papa, $doch, $sin)
{
     
    while($doch < count($mama) && $sin < count($papa) ) {
        if($mama[$doch] > $papa[$sin]) {
          echo $mama[$doch], " bolshe ",  $papa[$sin], "<br>";
        }
        elseif($mama[$doch] < $papa[$sin]) {
              echo $mama[$doch], " menshe ",  $papa[$sin], "<br>";
        }
        elseif($mama[$doch] == $papa[$sin]) {
              echo $mama[$doch], " ravno ",  $papa[$sin], "<br>";
        }
        $doch += 3;
        $sin += 2;
    }
}

-- а что если использовать в этой функции вместо while цикл foreach? Приведите пожалуйста альтернативное (ещё одно) решение именно с foreach.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

а что если использовать в этой функции вместо while цикл foreach? Приведите пожалуйста альтернативное (ещё одно) решение именно с foreach.

Подскажу/уточню: ведь оба массива равной длины, так что проблем с использованием foreach быть не должно (в качестве аргумента foreach можно использовать только один из них -- не важно какой)

_____________
матфак вгу и остальная классика =)

Сравните каждый 3-ий элемент 1-ого массива с каждым 2-ым элементом 2-ого массива

можно понимать, как если бы каждый с каждым нужно было сравнивать.

То есть 2-ой элемент первого массива с 3-м, 6-м, 9-м, ... второго массива, 4-й элемент первого массива с 3-м, 6-м, 9-м, ... второго массива, и т.д.

А не так, что для $i=1,\ 2,\ 3,\ldots$ только
$(2\cdot i)$-й элемент первого массива сравнивается с $(3\cdot i)$-м элементом второго.

vedro-compota's picture

Подразумевается попарное сравнение.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

не получается переделать на foreach

Ознакомьтесь с этим примечанием к задаче, там указана основная идея.

_____________
матфак вгу и остальная классика =)

vedro-compota's picture

<?php
 
function rand_array($chislo)
{
    for($i = 0; $i < $chislo; $i++) {
       $mas[$i] = rand(-30, 15);
    }
    return $mas;
}
  
function poluchaem_znachenie($arr)
{
    foreach($arr as $v) {
		echo ' | ', $v, ' | ';
    }
    echo "<br>";
}
 
/**
 * Функция проведен попарное сравнение элементов массива с учетом шага
 * 
 * @param array $arr1 -- первый массив
 * @param array $arr2 -- второй массив
 * @param integer $arr1Step шаг для первого массива (минимум 1)
 * @param integer $arr2Step шаг для второго массива (минимум 1)
 */
function compareArraysWithSteps($arr1, $arr2, $arr1Step, $arr2Step)
{ 
    $biggestStepArray = []; // для хранения массива с большим шагом
    $smallerStepArray = [];
    $biggestStep = 0; // тут будет храниться больший шаг
    $stepDistance = 0; /* тут будет хранится разница между 
     * "пройденными" индексами массивов
     */
     
    if ($arr1Step >= $arr2Step) { // определим где шаг больше, а где меньше
        $biggestStepArray = $arr1;
        $smallerStepArray = $arr2;
        $biggestStep = $arr1Step;
        $stepDistance = $arr1Step - $arr2Step;
    } else {
        $biggestStepArray = $arr2;
        $smallerStepArray = $arr1;
        $biggestStep = $arr2Step;
        $stepDistance = $arr2Step - $arr1Step;
    }
       
    $currentDistance  = $stepDistance;
     
    foreach ($biggestStepArray as $key => $value) {
        if (($key + 1) < $biggestStep) { // если не достигли первого элемента в массиве с большим шагом
            continue; 
        } else if ((($key + 1) % $biggestStep) == 0) { //  если делится на цело
            
           echoComparasion($value, $smallerStepArray[$key - $currentDistance]);
           $currentDistance += $stepDistance; /* с каждым шагом 
            * по большему массиву дистанция увеличивается 
            * на величину равную себе самой 
            */
        }
    }
}
 
/**
 * Сравнит два числа и выведет сообщение 
 * 
 * @param integer $val1
 * @param integer $val2
 */
function echoComparasion($val1, $val2)
{
    if ($val1 > $val2) {
    	echo $val1, " bolshe ",  $val2, "<br>";
    } elseif($val1 < $val2) {
		echo $val1, " menshe ",  $val2, "<br>";
    } elseif($val1 == $val2) {
		echo $val1, " ravno ",  $val2, "<br>";
    }
}
 
$n = 20;
$m1 = rand_array($n);
$m2 = rand_array($n);
poluchaem_znachenie($m1);
poluchaem_znachenie($m2);
// сравним каждый второй элемент в первом
// c каждым третьим во втором массиве
compareArraysWithSteps($m1, $m2, 2, 3);
?>

Также прошу обратить внимание на правила именования функций и переменных. Не надо давать имена типа "дочь" и "сын" -- в случае если это просто номера позиций (для массивов такие понятия не используются, обычно для деревьев, где есть иерархия). Имена должны быть максимально полными, простыми и понятными -- по ситуации.

Также не следует использовать транслит:

poluchaem_znachenie

лучше хоть как-то перевести на английский -- намного проще:

getValue();

_____________
матфак вгу и остальная классика =)

Я тоже подготовил решение.

<?php
function rand_array($chislo)
{
    for($i = 0; $i < $chislo; $i++) {
       $mas[$i] = rand(-30, 15);
    }
    return $mas;
}
  
function poluchaem_znachenie($arr)
{
    foreach($arr as $v) {
           echo $v, ', ';
    }
    echo "\n\n";
}
 
function sravnenie_m1_vs_m2($mama, $papa, $doch, $sin)
{
    
    $array_keys = array_keys($papa);
    
    $m = 0;
    
    foreach($mama as $value) {
        $m++;
        if ($m % $doch == 0) {
            $index_p = intdiv($m, $doch)*$sin;
            if (count($papa) >= $index_p) {
                $value_p = $papa[$array_keys[$index_p-1]];
                echo "Сравнивается \$m[$m]=$value с \$n[$index_p]=$value_p.\n";
            } else {
                break;
            }
        }
    }
    echo "\n";
}
 
$m1 = rand_array(13);
$m2 = rand_array(7);
 
poluchaem_znachenie($m1);
poluchaem_znachenie($m2);
$m = 2; // Каждый m-ый элемент из массива $m1
$n = 3; // И каждый n-ый элемент из массива $m2
sravnenie_m1_vs_m2($m1, $m2, $m, $n);
vedro-compota's picture

Решение math2, но с фактическим сравнением:

<?php
function rand_array($chislo)
{
    for($i = 0; $i < $chislo; $i++) {
       $mas[$i] = rand(-30, 15);
    }
    return $mas;
}
   
function poluchaem_znachenie($arr)
{
    foreach($arr as $v) {
           echo $v, ', ';
    }
    echo "\n\n";
}

function echoComparasion($val1, $val2)
{
    if ($val1 > $val2) {
        echo $val1, " bolshe ",  $val2, "<br>";
    } elseif($val1 < $val2) {
        echo $val1, " menshe ",  $val2, "<br>";
    } elseif($val1 == $val2) {
        echo $val1, " ravno ",  $val2, "<br>";
    }
}
  
function sravnenie_m1_vs_m2($mama, $papa, $doch, $sin)
{
     
    $array_keys = array_keys($papa);
     
    $m = 0;
     
    foreach($mama as $value) {
        $m++;
        if ($m % $doch == 0) {
            $index_p = intdiv($m, $doch)*$sin;
            if (count($papa) >= $index_p) {
                $value_p = $papa[$array_keys[$index_p-1]];
                //echo "Сравнивается \$m[$m]=$value с \$n[$index_p]=$value_p.\n";
                  echoComparasion($value, $value_p);
            } else {
                break;
            }
        }
    }
    echo "\n";
}
  
$m1 = rand_array(13);
$m2 = rand_array(7);
  
poluchaem_znachenie($m1);
poluchaem_znachenie($m2);
$m = 2; // Каждый m-ый элемент из массива $m1
$n = 3; // И каждый n-ый элемент из массива $m2
sravnenie_m1_vs_m2($m1, $m2, $m, $n);

_____________
матфак вгу и остальная классика =)