在整数数组上进行数学运算时如何翻转?

时间:2016-08-22 16:51:28

标签: php algorithm

因此,我尝试对整数数组进行数学运算,同时在数组的每个部分中强制执行最大整数。与此类似:

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]

所以我上面的工作有效但添加更大的整数时速度很慢。我试图通过按位移动来实现这一点,并且已经接近了,但是由于某些原因我无法让它工作。我想我需要第三方观点。有没有人有一些提示?

2 个答案:

答案 0 :(得分:1)

占用大部分时间的部分是while循环。您将反复减小该值,直到您具有小于100的值。但是,使用PHP循环播放会花费相当多的时间(在我的本地计算机上以超过20秒的速度运行12位整数)。相反,使用乘法和除法(以及if)。它的速度更快。使用此代码完成相同的12位整数不到一秒钟:

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循环重复时都会执行它,这也会增加执行函数的总时间。

另请注意,对于这样的大数学更改,您可能需要断言您希望计算的值范围,以确保没有异常值。我做了一个小范围,他们都出来了,但我鼓励你自己动手。

答案 1 :(得分:0)

使用min($max, $number)$number限制为$max

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