Задача № 19. Вывести на экран первых n простых чисел

<?php
 
 $n = 5 ; // Само число до которого нужно вывести все простые числа
 $f = 0 ; // Начальное значение счётчика -числа делителей
 $k=1; // Начальное значение параметра $k для цикла while
 $e=1; // Начальное значение переменной $e для цикла for 
 // Пояснение к выводу работы программы : 
 echo "()-в скобках значения параметра \$e-1 , а в ||
  значения простых делителей <BR>" ;
 
 
 
 
  //Выполняем цикл до тех пор пока $k не равно $n-заданному числу до 
 // которого необходимо вывести все простые числа
while ( $k !== $n )
{
	//  Цикл перебирает все числа до числа "первого ряда"
	for (  $e ; $e < $k ; $e++ )
        $e = $k;
	 {
		 echo "(",$e,")","<BR> "; 
		// Внутренний цикл , проверяющий простое ли число 
		 for ($i=1 ; $i <= $e ; $i++)
		 {
			           // Если наше число делится на любое натуральное  число меньшее  
					  // или равное ему без остатка то это делитель
				  if ($e % $i == 0 ) 
				  {
					  // Число делителей увеличивается на единичку
					  $f++ ;
				  }
				
			
		 }
			 // Если число натуральных делителей меньше двух или равно двум , 
			 // то это простое число.
				  if ($f<=2) 
				 {
					  // Выводим наше простое число 
					   echo "Вот они наши простые  делители   : ","|",$e ."|", " ";
				  }
	// Обнуляем количество делителей , теперь уже для другого числа
					  $f =0 ;
	 }
 $k++;   
}                   
 ?>
vedro-compota's picture

у вас отсутствуют комментарии к двум внешним циклам:

while ( $k !== $n )
{
 for ( $e = 1 ; $e < $k ; $e++ )
 {

объясните - зачем вы их используете.

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

fgh's picture

Решение данной задачи кроется в 3 циклах :

// Первый цикл while осуществляет прогонку чисел 
// до определенного числа назовём эти числа -"числа первого ряда"
while ( $k !== $n )
{
// Второй цикл for осуществляет  перебор всех
// натуральных чисел до заданного  числа из "чисел первого ряда "
 for ( $e = 1 ; $e < $k ; $e++ )
 {
// Третий цикл осуществляет подсчёт делителей числа 
//из  "чисел первого ряда " для определения его простоты
for ($i=1 ; $i <= $e ; $i++)
         {

Например "$n"=10 , то "$k" проходит значения 1,2,3,4,5,6,7,8,9,10 - это "числа первого ряда"
так вот $e принимает значения всех натуральных чисел до из ряда "чисел первого ряда"
и каждое число "второго ряда" проверяется на "простоту"

vedro-compota's picture

Решение данной задачи кроется в 3 циклах :

Это я уже "понял". Объясните первые два.

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

vedro-compota's picture

// Первый цикл while осуществляет прогонку отборов чисел до определенного числа
while (

во-первых что такое:

осуществляет прогонку отборов чисел

???
во вторых - а зачем, собственно, делать это "прогонку отборов"? Как она связана со вторым циклом и с условие задачи.

// Второй цикл for осуществляет перебор всех
// натуральных чисел до заданного "n"

вот это чётко и понятно. Перебор мы делаем потому, что ищем среди них.

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

fgh's picture

Осуществление прогонки чисел - это процесс перебора по порядку натуральных чисел до заданного числа n (p.s. с'умничал не к месту :)

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

vedro-compota's picture

то есть 1-ый цикл:

Осуществление прогонки чисел - это процесс перебора по порядку натуральных чисел до заданного числа n (p.s. с'умничал не к месту :)

при этом второй:

Второй цикл for осуществляет перебор всех натуральных чисел до заданного

То есть: ...я думаю, вы поняли. Перепишите код оптимальным образом (имеет место быть жуткое дублирование).

Да, можно при желании оптимизировать

Это желание никогда не должно оставлять вас =)

P. S.

p.s. с'умничал не к месту

Если вы про "научный стиль" - то к месту. Старайтесь чётко излагать мысли.

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

fgh's picture

Ценные замечания . ) Программист должен всегда всё оптимизировать. Это точно . Сейчас

vedro-compota's picture

 $e = 1;
while ( $k !== $n )
{
     for (  $e-1 ; $e < $k ; $e++ )
     {

$e-1 - это невменяемая конструкция, я даже точно не могу сказать фиксируется ли это значение один раз в начале как

$e = 1 - 1 = 0 

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

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

fgh's picture

Я предлагаю не раскрывать до конца тайны природы ))))))))))))))))))))))))))))))))

vedro-compota's picture

да $e=0
но если просто так и написать код не работает

значит $е изменяется с каждым витком - чтобы выяснить это, необходимо просто выводить переменную на экран (в данный момент подобное выяснение основной задачей не является).

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

fgh's picture

Спасибо за совет. Я так и сделал. Переменная $e выводится в скобочках "( ) ", а сами простые делители в знаках модуля " | | "

vedro-compota's picture

//Выполняем цикл до тех пор пока k не равно n-заданному числу до
// которого необходимо вывести все простые делители

какие "простые делители" ? о них в задаче ни слова.

// Цикл перебирает все числа до числа "первого ряда"

Какого "первого ряда"?? Формулируйте мысли ясно.

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

fgh,
единица не относится к простым числам. Нет необходимости выводить её.

Это не решение задачи 19, это решение задачи 18.

    //  Цикл перебирает все числа до числа "первого ряда"
     for (  $e ; $e < $k ; $e++ )

Этот цикл ничего не перебирает. Каждый раз выполняется лишь одна его итерация, так как
\$e отстаёт от \$k ровно на 1.

Более того, это ведёт к ошибке. Сделайте \$n = 30.
Программа выдаст простые числа лишь до 23 включительно. Почему?
Для того, чтобы тело цикла

    //  Цикл перебирает все числа до числа "первого ряда"
     for (  $e ; $e < $k ; $e++ )

было выполнено при (\$e == 29), нужно, чтобы было (\$e меньше \$k),
то есть \$k должен быть равен хотя бы 30. Но условие цикла

while ( $k !== $n )

не позволит это получить.

С большим успехом можно заменить эти строки на

    //  Цикл перебирает все числа до числа "первого ряда"
//     for (  $e ; $e < $k ; $e++ )
        $e = $k; 

и программа отработает точно так же, только без ошибки.

vedro-compota's picture

Это не решение задачи 19, это решение задачи 18

действительно...:

$n = 5 ; // Само число до которого нужно вывести все простые числа

в то время как в задаче указано что нужно вести конкретное кол-во простых чисел.

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

fgh's picture

Исправил . спасибо .

vedro-compota's picture

что вы исправили?

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

vedro-compota's picture

  • math, спасибо за ценный комментарий с анализом !)
  • fgh, настоятельно рекомендую вам вникнуть в комментарий math (как миниатюрное упражение по анализу кода), который не поленился точно указать причину бессмысленности одного из внешних циклов.

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