Reputation: 89
Hi guys I have the following class (it's a simple calculator). The subtract method accepts many parameter in input.
class Calculator {
public function sum($a, $b)
{
return $a + $b;
}
public function divide($a, $b)
{
return $a / $b;
}
public function subtract(int ...$b)
{
for ($i = 0; $i < count($b) - 1; $i++)
{
$oldValue = $b[$i];
$oldValue -= $b[$i+1];
}
return $oldValue;
}
}
$calc = new Calculator();
var_dump($calc->subtract(13,4,5));
How can I subtract more than 2 numbers?? I cannot find the right solution for the right implementation of public function subtract(int ...$b)
Someone could help me please?
Upvotes: 0
Views: 89
Reputation: 1139
<?php
public function subtract(int ...$b)
{
$num = $b[0]; // $num = 13;
unset($b[0]); // $b = arrray(4,5)
foreach ($b as $value) {
$num -= $value;
}
return $num;
}
EDIT
unset
will not reset index of the array where array_shift will reset the index of array, as per my previous experiments i am writing codes mostly without if conditions inside for loops whenever possible
unset
O(1) Time complexity
array_shift
O(n) Time complexity
BenchMarks
$max = 5000;
$times_a = [];
$times_b = [];
for ($i = 1; $i <= $max; $i += 1) {
$start = microtime(TRUE);
$array = range(0, 10000);
array_shift($array);
$end_time = microtime(TRUE);
$times_a[] = $end_time - $start;
//benchmark array lookups
$start = microtime(TRUE);
$array = range(0, 10000);
unset($array[0]);
$end_time = microtime(TRUE);
$times_b[] = $end_time - $start;
}
$times = 0;
foreach ($times_a as $key => $value) {
if($value > $times_b[$key]){
//if time of array_shift greater than unset
$times++;
}
}
echo $times . '<br>'; //4953
echo count($times_a); //5000
// Unset is More usefull
If inside forloop
$max = 50000;
$times_a = [];
$times_b = [];
$start_time = microtime(TRUE);
for ($i = 1; $i <= $max; $i += 1) {
$array = range(0, 10000);
$oldValue = null;
foreach($array as $num) {
if(is_null($oldValue)) {
$oldValue = $num;
} else {
$oldValue -= $num;
}
}
$end_time = microtime(TRUE);
}
$end_time = microtime(TRUE);
echo $end_time - $start_time;
//17.108186006546
Unset First variable initially
$max = 50000;
$times_a = [];
$times_b = [];
$start_time = microtime(TRUE);
for ($i = 1; $i <= $max; $i += 1) {
$array = range(0, 10000);
$num = $array[0];
unset($array[0]);
foreach ($array as $value) {
$num -= $value;
}
$end_time = microtime(TRUE);
}
$end_time = microtime(TRUE);
echo $end_time - $start_time;
//14.774175882339
Upvotes: 1
Reputation: 41820
Another way to do this is to shift the first number from the argument list, then subtract the sum of the remaining numbers.
public function subtract(int ...$b)
{
$a = array_shift($b);
return $a - array_sum($b);
}
It could also be simplified by modifying the function signature to accept a beginning number as well as a variable-length list of numbers to subtract from it.
public function subtract(int $a, int ...$b)
{
return $a - array_sum($b);
}
Upvotes: 0
Reputation: 23001
At the moment you're resetting $oldValue
each time, when you really need to set it in the beginning and go from there.
public function subtract(int ...$b)
{
$oldValue = null;
foreach($b as $num) {
if(is_null($oldValue)) {
$oldValue = $num;
} else {
$oldValue -= $num;
}
}
return $oldValue;
}
Upvotes: 0