为什么我的排序算法不起作用?

时间:2012-04-18 08:19:05

标签: php algorithm sorting

我正在为客户开发一个系统,该系统会创建一个包装标签的csv,并将其发送到打印机。客户有六个不同的项目。客户从我的客户那里批量订购产品。两个项目(产品A和产品B)共享相同的包装线。为了提高包装效率,我的客户希望首先在包装产品A和包装产品B之间进行交替。

例如,如果John,Sally和James都订购了这两种产品,系统需要将John的订单写入csv,从产品A开始,Sally的订单从产品B开始,James的订单再次从产品A开始。

我在下面粘贴了我的非工作代码,但这真的搞砸了我的脑袋,我真的很难用它。

foreach($orders as $order) {

    $name = null;
    $phone = null;

    $account = DAO_ContactPerson::get($order->account_id);
    $delivery = false;
    if($account->is_agency) {
        $name = $order->getAttribute('name');
        $phone = $order->getAttribute('phone');
    } else {
        $name = sprintf("%s %s",
            $account->getPrimaryAddress()->first_name,
            $account->getPrimaryAddress()->last_name
        );
        $phone = $account->phone;
    }

    $name = trim($name);
    $phone = trim($phone);
    $items = $order->getItems();

    if($order->getAttribute('delivery')) {
        $type = 'deliveries';
        $destination = 'Delivery';
        $address = sprintf("%s %s %s",
            $order->getAttribute('delivery_address.line1'),
            $order->getAttribute('delivery_address.line2'),
            $order->getAttribute('delivery_address.postal')
        );
    } else {
        $type = 'pickups';
        $agency = DAO_ContactPerson::getAgency($order->getAttribute('pickup'));
        $destination = $agency->name;

        // Override account id so orders are grouped by agency
        $order->account_id = $agency->id;
        $address = null;
    }
//          var_dump($order->id);
    // Init account array
    if(!isset($rows[$type][$order->account_id]))
        $rows[$type][$order->account_id] = array('combined' => array(), 'separate' => array());

    foreach($items as $item) {
        $packing = 'separated';
        if($item->product_id == 3 || $item->product_id == 4)
            $packing = 'combined';

        if(!isset($rows[$type][$order->account_id][$packing][$item->product_id]))
            $rows[$type][$order->account_id][$packing][$item->product_id] = array();
        $i = 0;
        while($i < $item->quantity) {
            $rows[$type][$order->account_id][$packing][$item->product_id][] = array(
                    'number' => $order->id,
                    'destination' => $destination,
                    'size' => $item->product_id,
                    'name' => $name,
                    'address' => $address,
                    'phone' => $phone
                );
            $i++;
        }

    }
//          if($order->id == 176) {
//              var_dump($rows[$type][$order->account_id][$packing]);
//          }
}

$this->weight = 1;

$pickups = count($rows['pickups']);
for($i = 0; $i < $pickups; $i++) {
    $account =& $rows['pickups'][$i];
    $account['output'] = array();
    if(isset($account['combined'])) {
        $combined_products =& $account['combined'];
        if(!empty($combined_products)) {
            foreach($combined_products as $prod_id => $combined) {
                usort($combined_products[$prod_id], array($this, "_compareBoxes"));
            }
            // Flip weights once we finish with this account
            $last_box = end($combined_products);
            $last_box = array_pop($last_box);
            reset($combined_products);
            if($this->weight == 1) {
                $this->weight = -1;
                if($last_box['size'] == 3) {
                    asort($combined_products);
                }
            } else {
                if($last_box['size'] == 4) {
                    arsort($combined_products);
                }
                $this->weight = 1;
            }
            foreach($combined_products as $combined) {
                $account['output'][] = $combined;
            }
            foreach($account['separated'] as $separate) {
                $account['output'][] = $separate;
            }
        }
    } else {
        if(isset($account['separated']))
            $account['output'] = $account['separated'];
    }
}

$deliveries = count($rows['deliveries']);
for($i = 0; $i < $deliveries; $i++) {
    $account =& $rows['deliveries'][$i];
    $account['output'] = array();
    if(isset($account['combined'])) {
        $combined_products =& $account['combined'];
        if(!empty($combined_products)) {
            foreach($combined_products as $prod_id => $combined) {
                usort($combined_products[$prod_id], array($this, "_compareBoxes"));
            }
            // Flip weights once we finish with this account
            $last_box = end($combined_products);
            $last_box = array_pop($last_box);
            reset($combined_products);
            if($this->weight == 1) {
                $this->weight = -1;
                if($last_box['size'] == 3) {
                    asort($combined_products);
                }
            } else {
                if($last_box['size'] == 4) {
                    arsort($combined_products);
                }
                $this->weight = 1;
            }
            foreach($combined_products as $combined) {
                $account['output'][] = $combined;
            }
            foreach($account['separated'] as $separate) {
                $account['output'][] = $separate;
            }
        }
    } else {
        if(isset($account['separated']))
            $account['output'] = $account['separated'];
    }
}

$rows['output'] = $rows['pickups'];
array_push($rows['output'], $rows['deliveries']);

$output = '';
foreach($rows['output'] as $account_id => $boxes) {
    if(!empty($boxes['output'])) {
        foreach($boxes['output'] as $labels) {
            if(!empty($labels)) {
                foreach($labels as $label) {
                    $output .= implode(',', $label) . "<br>";
                }
            }
        }
    }
}

_compareBoxes方法如下所示:

private function _compareBoxes($a, $b) {
    if($a['size'] == $b['size']) {
        return 0;
    }
    if($this->weight == 1) {
        // Medium first, then Large
        return ($a['size'] < $b['size']) ? -1 : 1;
    }
    if($this->weight == -1) {
        // Large first, then Medium
        return ($a['size'] > $b['size']) ? -1 : 1;
    }
}

0 个答案:

没有答案