Был проект в школе кодирования некоторое время назад в JS, где мы использовали Сито Эратосфена (Я не могу не читать это каким-то громким, эхом голосом), чтобы вывести все простые числа вплоть до введенного пользователем числа. Код, который мы придумали для этого:
var primeSifter = function(number) {
var numArray = numberList(number);
var prime = 2;
var count = 0;
while (prime <= number) {
numArray.forEach(function(num) {
if ((num !== prime) && (num % prime === 0)) {
numArray.splice(numArray.indexOf(num), 1);
}
});
count++;
prime = numArray[count];
}
return numArray;
}
Numberlist () это просто функция, которая создает массив чисел от 2 до любого числа, которое вводит пользователь.
count++;
prime = numArray[count];
Идея здесь состояла в том, чтобы пропустить поиск кратных чисел, которые уже были удалены, установив простое число равным следующей позиции индекса numArray
, который должен быть следующим по величине простым числом. Это то, что я хотел бы выяснить, как реализовать в PHP. Я могу подтвердить, что это работает. В PHP однако …
В оригинальном, неотредактированном посте я использовал unset
вместо array_splice
, За ответом грустного парня я начал играть с ними обоими.
Этот код дает ошибки, показанные ниже, независимо от того, unset
или же array_splice
,
function number_list($input) {
$numList = array();
for ($i = 2; $i <= $input; $i++) {
array_push($numList, $i);
}
return $numList;
}
function sift_primes($input) {
$numArray = number_list($input);
$prime = 2;
$count = 0;
while ($prime <= $input) {
foreach ($numArray as $key => $num) {
if (($num !== $prime) && ($num % $prime === 0)) {
array_splice($numArray, $key, 1);
}
}
$count++;
$prime = $numArray[$count];
}
return $numArray;
}
Это то, что я изначально пришел сюда, чтобы выяснить: как эти две функции принципиально различаются в JS и PHP?
Следующее является своего рода расширением исходного вопроса:
Единственный способ, который я нашел, чтобы эта функция возвращала действительный вывод, это заменить:
$count++;
$prime = $numArray[$count];
С:
$prime++;
Однако даже когда это дает мне вывод, unset
а также array_splice
дай мне разные результаты.
Этот код выводит Array ( [0] => 2 [1] => 3 [2] => 5 [3] => 9 )
, что не правильно, так как 9, очевидно, не простое число:
function sift_primes($input) {
$numArray = number_list($input);
$prime = 2;
$count = 0;
while ($prime <= $input) {
foreach ($numArray as $key => $num) {
if (($num !== $prime) && ($num % $prime === 0)) {
array_splice($numArray, $key, 1);
}
}
$prime++;
}
return $numArray;
}
Замена array_splice
с unset($numArray[$key])
возвращает:
Array ( [0] => 2 [1] => 3 [3] => 5 [5] => 7 )
, правильный ответ.
Вопрос НЕ «Как получить желаемый результат?» Я думаю, что я уже понял, как это сделать. Я действительно пытаюсь понять, что происходит за кулисами в обоих языках, чтобы сделать правильный подход в JS (первый блок кода выше) недопустимым в PHP (в частности, почему я не могу установить $prime
быть следующим простым числом в массиве после объединения не простых чисел?). Кажется, что они обрабатывают сращивания по-разному на фундаментальном уровне (и, очевидно, PHP даже обрабатывает unset
а также array_splice
по-другому, что, возможно, является продолжением первого вопроса), что кажется действительно ценной вещью, которую нужно понять.
Это ссылки выше
Примечание: неопределенное смещение: 2 в /Users/Guest/Desktop/test/sift.php on
строка 23Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18Примечание: неопределенное смещение: 4 в /Users/Guest/Desktop/test/sift.php on
строка 23Предупреждение: деление на ноль в /Users/Guest/Desktop/test/sift.php на
строка 18
И так далее, и так далее …
Я пошел дальше и немного перестроил / отформатировал, чтобы попытаться лучше сформулировать проблему. Это было главным образом в ответ на ответ «грустный чувак», в котором он предложил использовать array_splice
вместо unset
, Рассуждения, казалось, имели полный смысл, но я обнаружил, что они, похоже, не дают ожидаемого результата.
Спасибо всем, кто нашел время, чтобы пройти через это. Я впервые пытаюсь получить ответ здесь, мои извинения, если я делаю это более сложным, чем это должно быть.
unset($a[idx])
больше похоже a[idx] = undefined
чем splice
,
Вы можете проверить себя:
$a = [0, 1, 2, 3];
unset($a[1]);
print_r($a);
Приведет к:
Array
(
[0] => 0
[2] => 2
[3] => 3
)
Так что взяв $prime = $numArray[$count];
вы попадете в те пустые места, которые будут преобразованы в 0
для операции разделения. Вы должны либо использовать array_splice
или реорганизовать свой код.
Других решений пока нет …