簡體   English   中英

php有內置的數組函數,可以為布爾結果排序/賦值嗎?

[英]does php have built-in array functions that can sort/assign values for boolean result?

我有一系列訂單,key代表訂單#。 每個元素都包含一系列員工,可以履行員工編號所代表的訂單。

[0] =>         // <-- order#
    [0] => 0,
    [1] => 1,
    [2] => 2

[1] =>
    [0] => 0,
    [1] => 1,
    [2] => 2

[2] =>
    [0] => 3

[3] =>
    [0] => 3

所以訂單0可以由員工0,1或2.訂單1來履行。 訂單2和3只能由員工3履行。

我需要返回bool,如果每個訂單都有一個唯一的員工來實現它,那就是真的。 因此,在這種情況下返回false,因為只有一名員工可以履行訂單2和3,並且無法分配給他們。

我希望這是有道理的。 在我的手機上輕拍這個

這是一個我快速編寫的php函數,可以完成你想要的,我已經快速測試了它,它似乎正常工作。

<?php

function compare($orders){

    if(sizeof($orders) == 0){
        return 1;
    }
    $quantity = array();
    foreach ($orders as $order) {
        if(sizeof($order) == 0){
            return 0;
        }
        foreach ($order as $employee) {
            if(array_key_exists($employee, $quantity)){
                $quantity[$employee]++;
            }
            else{
                $quantity[$employee] = 1;
            }
        }
    }
    $chosenEmployees = array_keys($quantity, min($quantity));
    $chosenEmployee = $chosenEmployees[0];

    $length = array();
    foreach ($orders as $key => $order) {
        $length[$key] = sizeof($order);
    }
    for ($i=0; $i < sizeof($orders); $i++) {
        $chosenOrders = array_keys($length, min($length));
        foreach ($chosenOrders as $orderKey) {
            if(in_array($chosenEmployee, $orders[$orderKey])){
                unset($orders[$orderKey]);
                foreach ($orders as $key1 => $order) {
                    foreach ($order as $key2 => $employee) {
                        if($employee == $chosenEmployee){
                            unset($orders[$key1][$key2]);
                        }           

                    }
                }
                return compare($orders);
            }
            else{
                unset($length[$orderKey]);
            }
        }
    }

}
$out = compare($orders);
?>

要使用它,請鍵入compare($ your_array_name),該函數將返回0(false)或1(true)。
希望能幫助到你。

編輯:
我懷疑你會在其他任何地方找到這個代碼,因為我是為這個問題寫的。
我一直在研究證明,並且可以證明當函數返回true時,它是真的。

該函數返回true。
=> orders數組為空。
=>在此之前,orders數組包含一個訂單,該訂單至少可由一個員工完成。
=>在此之前,orders數組包含兩個訂單,分別至少由員工1和員工2完成。
通過重復,我們可以在結束之前推斷出n個步驟,有n個訂單,所有訂單都由至少一個唯一的員工執行。
如果n =初始數組的大小,我們可以得出結論,如果函數返回true,則它是正確的。

如果此證明不正確,請告訴我。 如果我找到下半場的證據,我會再次編輯我的帖子。

一種解決方案是使用array_reducearray_diff來推測性地將員工分配給訂單。

//Each step tries to add another employee id to the $carry array
function calc($carry, $item) 
{
    if (!$carry) {
        $carry = array();
    }
    $diff = array_diff($item, $carry);
    if (count($diff) > 0) {
        array_push($carry, reset($diff));
    }
    return $carry;
}

function cmp($a, $b)
{
    return count($a) - count($b);
}

function checkCondition($arrayToCheck) 
{
    uasort($arrayToCheck, 'cmp');
    $reduced = array_reduce($arrayToCheck, "calc");

    //If we have a shorter array than the number of orders, we have a problem
    return count($reduced) == count($arrayToCheck);
}

$o = array(
    array(0,1,2),
    array(0,1,2),
    array(3),
    array(3),
);

$result = checkCondition($o);

echo $result + " " + $result ? "Good" : "Bad";  //Should be Bad

$o = array(
    array(0,1,2),
    array(0,1,2),
    array(1),
    array(3),
);

$result = checkCondition($o);

echo $result + " " + $result ? "Good" : "Bad";  //Should be Good

首先對數組進行排序可以避免將工作人員“分配”給必須分配給以后訂單的訂單的問題。

算法

您的主要問題是關於算法。 如上所述,該語言具有次要意義。

你想要的是什么

檢查每個訂單是否可以分配一個員工,每個員工是否分配了一個訂單

您可以像圖表一樣繪制它:

  • 節點是訂單和員工
  • 鏈接是可能的分配

所以你想要刪除所有必要的鏈接

  • 每個員工節點都有一個或沒有鏈接,和
  • 每個訂單節點仍然有一個 (或多個)鏈接

如果您成功,您有一個解決方案,並希望算法返回true 否則,它應該返回false


編輯:J。Quick發現一個非常簡單的實現工作。 我很想得到它的證明或參考他發現它的地方。

所以我在這里解釋一下:

  1. 如果訂單為空,則返回true
  2. 如果訂單的任何訂單沒有員工,則返回false
  3. 以最少的訂單獲得員工e
  4. 獲得E“的訂單Ø與員工數最少
  5. 訂單中刪除eo
  6. 從1開始重復。

JavaScript實現

function areAllOrdersFulfilled(orders) {
    while (orders.length !== 0) {
        if (undefined !== orders.find( o => o.length === 0))
            // An order has no employee to fulfill it
            return false;
        // Get employee and order to remove
        let employees = [];
        orders.forEach( order => {
            order.forEach( employee => {
                employees[employee] = (employees[employee] || 0) + 1;
            });
        });
        let employeeToRemove = employees.indexOf(employees.slice().sort()[0]), // Employee with less orders
            orderToRemove = orders
                .sort( (o1, o2) => o1.length - o2.length ) // In-place sort orders
                .findIndex( o => o.includes(employeeToRemove)); // Order with less employees
        // Remove
        orders.splice(orderToRemove,1);
        orders = orders.map( o => o.filter(e => e !== employeeToRemove) )
    }
    return true;
}

你可以像這樣運行它:

const orders = [
    [0,1,2],
    [0,1,2],
    [3],
    [3]
];

console.log(areAllOrdersFulfilled(orders));

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM