如何在整数数组上做数学运算


How do I roll over when doing math on an array of integers?

所以我试图在整数数组上做数学,同时在数组的每个部分强制执行最大整数。类似于:

function add($amount) {
  $result = array_reverse([0, 0, 0, 100, 0]);
  $max = 100;
  for ($i = 0; $i < count($result); ++$i) {
    $int = $result[$i];
    $new = $int + $amount;
    $amount = 0;
    while ($new > $max) {
      $new = $new - $max;
      ++$amount;
    }
    $result[$i] = $new;
  }
  return array_reverse($result);
}
add(1); // [0, 0, 0, 100, 1]
add(100); // [0, 0, 0, 100, 100]
add(101); // [0, 0, 1, 0, 100]

所以我上面的工作,但它是缓慢的,当添加较大的整数。我试过用位变换来做这件事,并且接近了,但由于某种原因,我就是不能让它工作。我想我需要第三方的意见。有人有什么建议吗?

占据大部分时间的是while循环。你不断减少这个值,直到你得到一个低于100的值。但是,使用PHP进行这样的循环需要非常多的时间(在我的本地机器上,一个12位数的整数需要超过20秒的时间)。相反,使用乘法和除法(以及if)。它快了几个数量级。同样的12位整数用下面的代码完成用时不到1秒:

function add($amount) {
    $result = array_reverse([0, 0, 0, 100, 0]);
    $max = 100;
    for ($i = 0, $size = count($result); $i < $size; ++$i) {
        $int = $result[$i];
        $new = $int + $amount;
        $amount = 0;
        if( $new > $max ) {
            $remainder = $new % $max;
            // Amount is new divided by max (subtract 1 if remainder is 0 [see next if])
            $amount = ((int) ($new / $max));
            // If remainder exists, new is the the number of times max goes into new 
            // minus the value of max. Otherwise it is the remainder
            if( $remainder == 0 ) {
                $amount -= 1;
                $new = $new - ((($new / $max) * $max) - $max);
            } else {
                $new = $remainder;
            }
        }
        $result[$i] = $new;
    }
    return array_reverse($result);
}

还请注意,我将count($result)调用移到了for循环的变量初始化部分。当它在表达式段内时,每次for循环重复时都会执行它,这也会增加执行函数的总时间。

还要注意,对于像这样的大型数学更改,您可能希望断言期望计算的值范围,以确保没有异常值。我做了一个小范围的测试,结果都是一样的,但我鼓励你们自己做。

min($max, $number)使$number只限于$max

for ($i = 0; $i < count($result); ++$i) {
    $result[$i] = min($max, $result[$i] + $amount);
}