我需要根据一系列重量规则找到运输箱子的成本,类似于这样:

$rules = [
    '1'     => '1.2',
    '5-10'  => '6.25',
    '10-15' => '9.2',
    '15-20' => '10.9',
];

因此,根据这个数组,一个重47磅的盒子的运输成本为10.90 + 10.90 + 6.25 = 28.05美元.

这是因为47将消耗两倍的范围(15-20)和一倍的范围(5-10).(表示>方程符号,而]表示<=方程符号.

首先,为了简单起见,我创建了一个中间数组(每个范围规则的上限),就像这样(1没有上/下限,但很容易排除):

$tiers = [
    20,
    15,
    10,
    1,
];

然后我try 以类似于因式分解过程的方式将初始权重分配给该array.所以一开始我完全忽略了下限,拿了一个重量,即.37.75磅.然后,使用以下代码,我生成每个权重层的"因子分解"数组:

print_r( distribute( 37.75 );

function distribute( $weight = 0 ) {
    $tiers = [1, 10, 15, 20];

    rsort( $tiers );

    foreach ( $tiers as $tier ) {
        $counters[$tier] = 0;
    }

    foreach ( $tiers as $tier ) {
        $quotient  = $weight / $tier;
        $floored   = floor( $quotient );
        $remaining = $weight - $floored * $tier;

        if ( $quotient >= 1 && $remaining > 1 ) {
            $counters[$tier] = $floored;
            $weight          = $remaining;
        } else if ( $tier == 1 ) {
            $counters[$tier] = ( $floored + 1 );
            $weight          = $weight - ( $floored + 1 ) * $tier;
        }
    }

    return $counters;
}

这方便地产生了这样的输出:

    Array (
        [20] => 1
        [15] => 1
        [10] => 0
        [1] => 3
    )

然后,我try 了同样的权重为38的代码,并意识到我的第一个错误……边缘情况有一些问题,我还无法弄清楚,38仍然会在1层规则中增加+1.

然后,我try 了47.75磅,发现了第二个错误……正如我所说,为了简单起见,我使用了上限,这会扰乱权重的"因式分解".因此,对于47.75磅,上面的代码会产生这样的输出:

    Array (
        [20] => 2
        [15] => 0
        [10] => 0
        [1] => 8
    )    

这是完全错误的,因为1层不能消费8次,因为8(准确地说是7.99)属于(5-10]范围.

总而言之,不幸的是,我的方法在很多方面都存在缺陷.有人能帮我找出正确的代码来处理这个问题吗?

推荐答案

我发现体重范围的不一致 struct 很难处理,但我完全理解为什么需要这样做--以便正确计算个人磅数.

我创建了一个脚本,试图找到最便宜的合格层,记录层数据,从输入权重中减go 范围的最大值,然后重复. 这似乎适用于我创建的所有测试.

代码:(Demo)

function costFromWeight($weight, array $newRules): array {
    $parsed = [];
    foreach ($newRules as $range => $cost) {
        if (sscanf($range, '%d-%d', $min, $max) === 1) {
            $default = [$min, $min, (float) $cost];
        } else {
            $parsed[]  = [$min, $max, (float) $cost];
        }
    }
    
    $result = ['cost' => 0];
    while ($weight > 0) {
        foreach ($parsed as $i => [$min, $max, $cost]) {
            if ($weight <= $max) {
                if (!$i && $weight <= $min) {  // weight is lower than lowest range, use defaults
                    [$min, $max, $cost] = $default;
                }
                break;
            }
        }
        $result[$max] = ($result[$max] ?? 0) + 1;
        $result['cost'] += $cost;
        $weight -= $max;
    }
    return $result;
}

$rules = [
    '1'   => '1.2',
    '5-10'  => '6.25',
    '10-15' => '9.2',
    '15-20' => '10.9',
];

foreach ([49, 47.75, 38, 35, 23, 15, 14, 10.5, 4] as $weight) {
    echo "$weight :: ";
    print_r(costFromWeight($weight, $rules));
    echo "\n---\n";
}

输出:

49 :: Array
(
    [cost] => 28.05
    [20] => 2
    [10] => 1
)

---
47.75 :: Array
(
    [cost] => 28.05
    [20] => 2
    [10] => 1
)

---
38 :: Array
(
    [cost] => 21.8
    [20] => 2
)

---
35 :: Array
(
    [cost] => 20.1
    [20] => 1
    [15] => 1
)

---
23 :: Array
(
    [cost] => 14.5
    [20] => 1
    [1] => 3
)

---
15 :: Array
(
    [cost] => 9.2
    [15] => 1
)

---
14 :: Array
(
    [cost] => 9.2
    [15] => 1
)

---
10.5 :: Array
(
    [cost] => 9.2
    [15] => 1
)

---
4 :: Array
(
    [cost] => 4.8
    [1] => 4
)

---

Php相关问答推荐

根据类别在WooCommerce中添加库存数量后缀

Laravel中的通配符Undot数组

基于验证动态更改输入字段类(名称密码)&

按制造商、型号和年份范围判断数据的存在性

自定义WooCommerce查询字符串仅显示前3个产品

以编程方式更新现有Yith WooCommerce Booking的状态

WooCommerce在store 页面上显示兼容多语言的产品属性

PHP原始数据读取引发max_input_vars错误

将客户重定向到自定义感谢页后的空白页

laravel中获取的数据会自动更改时间戳值

PHP:为什么递归需要这么长时间

shell_exec运行大型数据处理

Mac 上安装 php 时出现 Homebrew 错误

在 WooCommerce 中何时何地执行 woocommerce_order_status_completed_notification 挂钩?

在 WooCommerce 中应用优惠券时显示购物车商品折扣金额

如何更新 Laravel Eloquent 列强制转换为集合

PHP 中的 libgd 无法读取 Apache 配置中的 SetEnv GDFONTPATH

根据购买产品的自定义字段替换WooCommerce添加到购物车按钮

如何设置Mailersend PHP API 模板变量?

Docker: unixodbc.h 没有这样的文件或目录.已安装 unixodbc-dev 时出现pecl install sqlsrv错误