【问题标题】:Why does this work in JS and not PHP?为什么这适用于 JS 而不是 PHP?
【发布时间】:2015-11-04 23:03:24
【问题描述】:

不久前在 JS 的编码学校做过一个项目,我们使用 Eratosthenes 的筛子(我无法用某种轰隆隆的回声声音读出来)输出所有质数直到用户输入的数字。我们为此提出的代码是:

JavaScript 代码示例

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 中...

PHP 代码示例

在未经编辑的原始帖子中,我使用了unset 而不是array_splice。根据 A Sad Dude 的回答,我开始和他们两个一起玩。

无论我是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++;

但是,即使它给了我一个输出,unsetarray_splice 给我的结果也不同。

这段代码输出Array ( [0] =&gt; 2 [1] =&gt; 3 [2] =&gt; 5 [3] =&gt; 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] =&gt; 2 [1] =&gt; 3 [3] =&gt; 5 [5] =&gt; 7 ),正确答案。

主要问题:

问题不是“我如何获得我想要的输出?”我相信我已经想出了如何做到这一点。我真的很想了解两种语言在幕后发生的事情,以使 JS 中的有效方法(上面的第一个代码块)在 PHP 中无效(具体来说,为什么我不能将 $prime 设置为下一个素数拼接非素数后数组中的数字?)。似乎它们在基本层面上处理拼接的方式不同(显然 PHP 甚至处理 unsetarray_splice 的方式也不同,这可能是第一个问题的延伸),这似乎是一件非常值得理解的事情。

错误信息

以上引用了这些

注意:未定义的偏移量:2 在 /Users/Guest/Desktop/test/sift.php 上 第 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 in /Users/Guest/Desktop/test/sift.php on 第 23 行

警告:在 /Users/Guest/Desktop/test/sift.php 中除以零 第 18 行

不断地不断地......

编辑

我继续进行了一些重新排列/格式化,以尝试更好地阐明问题。这主要是为了回应“一个悲伤的家伙”的回复,他在回复中建议使用array_splice 而不是unset。推理似乎完全有道理,但我发现它似乎并没有达到预期的结果。

感谢任何花时间涉足此问题的人。第一次尝试在这里得到答案,如果我使它变得比需要的更困难,我深表歉意。

【问题讨论】:

  • JS 支持被零除,PHP 不支持 :)。所以 PHP 不喜欢 8 / 0。你应该在 PHP 中进行操作之前检查你的变量值。我看到的唯一操作是$num % $prime。所以检查 $prime 和 $num。
  • 不知何故,$prime 的值为 0。我会检查你的 number_list 函数。
  • 我在上面包含了 number_list 函数。如果存在未定义的偏移量,那么将 $prime 分配给“NULL”或“未定义”是否有意义,这与尝试除以 0 相同?我想我只是不知道 array_splice 或 Array.splice() 在两种语言之间的工作方式有何不同。在 JS 中,似乎当它拼接数组时,它只是将键重新分配给适当的值,所以第一次 numArray[2] = 3 ,然后在第一个循环之后 numArray[2] = 5 。问号?

标签: javascript php arrays array-splice


【解决方案1】:

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,或者重新组织您的代码。

【讨论】:

  • 谢谢。我已将其更改为 array_splice($numArray, $key, 1);不幸的是,它对更大的问题没有帮助。
  • 不确定我是否理解。您仍然通过零错误获得 div 吗?你能发布更新的代码吗?
  • 我很抱歉,还是有点新。即将在波特兰的一所代码学校结束四个月的学习。我明白你在说那些空白点。看起来我们在这里处理了几个变量。首先:无论我是 $count++$prime = $numArray[$count]; 还是只是 $prime++。只有后者返回一个有效的输出(即一个数组),不管我是unset 还是array_splice。第二:当我得到实际输出时(使用$prime++),array_splice 给我 2、3、5、9(错误),而unset 给我 2、3、5、7(正确)。一秒钟内发布完整代码。
猜你喜欢
  • 2020-09-07
  • 2012-06-23
  • 1970-01-01
  • 1970-01-01
  • 2014-11-06
  • 2018-04-24
  • 2020-11-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多