我之前尝试过这个问题,但我不认为我正确地表达了这个问题,所以我找到了一些能让我得到结果的东西,现在我希望它会帮助别人帮助我。
问题:我有10个项目。如果你买1,它的价格是10美元。我会以9美元的价格卖给你第二个。我会以8美元的价格卖给你第三件商品。我将继续取钱,直到我们达到5美元/项目,因为这是我将出售的最低价格。所以,如果你全部买10,那么你将花费65美元。
这是我试图实现的定价模式,除非规模更大。而不是使用美元的少数项目,我谈论的数百万,并使用几分钱。
这是我目前的代码:
<?php
function getCost($num_items)
{
$min_price = 0.002;
$max_price = 0.007;
$discount_range = 1000000;
$discount_per_additional_item = ($max_price - $min_price) / ($discount_range - 1);
$price_per_unit = MAX($min_price, ($max_price - ($num_items - 1) * $discount_per_additional_item) );
return $price_per_unit;
}
$array = [100, 1000, 10000, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000];
foreach ($array as $value)
{
$sum = 0;
for ($i = 0; $i < $value; ++$i)
$sum += getCost($i);
echo number_format($value) . ' | $' . number_format($sum) . "\n";
}
结果是:
100 | $1
1,000 | $7
10,000 | $70
100,000 | $675
200,000 | $1,300
300,000 | $1,875
400,000 | $2,400
500,000 | $2,875
600,000 | $3,300
700,000 | $3,675
800,000 | $4,000
900,000 | $4,275
1,000,000 | $4,500
我使用$ array作为一个完整性检查,在现实世界中,我只是计算客户收取的实际数量。
我的问题是:有没有办法在不使用for循环的情况下完成此操作?或许更优雅的东西?
我在网上做了一个例子:http://sandbox.onlinephpfunctions.com/code/47e270dbad8cbe16c9ea906ffd2dce098a52fbca
答案 0 :(得分:4)
此代码将具有相同的输出,并且没有内部循环:
$min_price = 0.002;
$max_price = 0.007;
$discount_range = 1000000;
$discount_per_additional_item = ($max_price - $min_price)/($discount_range - 1);
$num_progressively_discounted_items =
ceil(($max_price - $min_price) / $discount_per_additional_item);
foreach ($array as $value) {
$num_items_above_min = min($value, $num_progressively_discounted_items);
$num_items_at_min = $value - $num_items_above_min;
$sum = $num_items_at_min * $min_price +
$num_items_above_min * $max_price -
$discount_per_additional_item
* $num_items_above_min * ($num_items_above_min - 1)/2;
echo number_format($value) . ' | $' . number_format($sum) . "\n";
}
这就是它的作用:
0+1+2+3+4+5...+n
。就像我在评论中提到的那样,您的代码中存在一些奇怪的内容:对于n(n-1)/2
,$i=0
返回的值高于最高价格,因为单位折扣会添加到其中。这可以通过使用getCost($i)
启动内部循环来纠正。无论如何,这意味着我提出的代码的结果有微小的差异,因为它没有这种特性。但由于单位折扣非常小,因此您不会在打印输出中注意到它。
答案 1 :(得分:0)
你可以多做一点功能风格:
function sumOfNaturalSeries($n)
{
return ((1 + $n) / 2) * $n;
}
$minPrice = 0.002;
$maxPrice = 0.007;
$discountRange = 1000000;
$discountStep = ($maxPrice - $minPrice) / $discountRange;
$getPrice = function ($numberOfItems) use (
$minPrice,
$maxPrice,
$discountRange,
$discountStep
) {
if ($numberOfItems <= $discountRange) {
return $maxPrice * $numberOfItems - sumOfNaturalSeries($numberOfItems - 1) * $discountStep;
}
$itemsAboveRange = $numberOfItems - $discountRange;
return $maxPrice * $discountRange - sumOfNaturalSeries($discountRange - 1) * $discountStep + $minPrice * $itemsAboveRange;
};
$array = [100, 1000, 10000, 100000, 200000, 300000, 400000, 500000, 600000, 700000, 800000, 900000, 1000000];
$sums = array_map($getPrice, $array);
var_dump($sums);
var_dump(array_map('number_format', $sums));
这是demo。
注意计算错误。