[英]does php have built-in array functions that can sort/assign values for boolean result?
I have an array of orders, key represents order#. 我有一系列订单,key代表订单#。 each element contains an array of employees that can fulfill those orders represented by employee number.
每个元素都包含一系列员工,可以履行员工编号所代表的订单。
example 例
[0] => // <-- order#
[0] => 0,
[1] => 1,
[2] => 2
[1] =>
[0] => 0,
[1] => 1,
[2] => 2
[2] =>
[0] => 3
[3] =>
[0] => 3
so order 0 can be fulfilled by employee 0,1, or 2. order 1 as well. 所以订单0可以由员工0,1或2.订单1来履行。 orders 2 and 3 can only be fulfilled by employee 3.
订单2和3只能由员工3履行。
i need to return bool which is true if each order has one unique employee to fulfill it. 我需要返回bool,如果每个订单都有一个唯一的员工来实现它,那就是真的。 so in this case return false because only one employee is available to fulfill orders 2 and 3 and cant be assigned to both.
因此,在这种情况下返回false,因为只有一名员工可以履行订单2和3,并且无法分配给他们。
i hope that makes sense. 我希望这是有道理的。 tapping this out on my phone agh
在我的手机上轻拍这个
This is a php function I wrote quickly that does what you want, I have quickly tested it and it seems to work properly. 这是一个我快速编写的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);
?>
To use it, type compare($your_array_name), and the function will return 0 (false) or 1 (true). 要使用它,请键入compare($ your_array_name),该函数将返回0(false)或1(true)。
Hope it helps. 希望能帮助到你。
Edit: 编辑:
I doubt you'll find this code anywhere else because I wrote it for this question. 我怀疑你会在其他任何地方找到这个代码,因为我是为这个问题写的。
I have been working on proof and can prove that when the function returns true, it is true. 我一直在研究证明,并且可以证明当函数返回true时,它是真的。
The function returned true. 该函数返回true。
=> The orders array is empty. => orders数组为空。
=> Before that, the orders array contained one order that can be done by at least employee one. =>在此之前,orders数组包含一个订单,该订单至少可由一个员工完成。
=> Before that, the orders array contained two orders that can be done respectively by at least employee one and employee two. =>在此之前,orders数组包含两个订单,分别至少由员工1和员工2完成。
Via recurrence, we can deduce that n steps before the end, there were n orders, all doeable by at least one unique employee. 通过重复,我们可以在结束之前推断出n个步骤,有n个订单,所有订单都由至少一个唯一的员工执行。
If n = size of initial array, we can conclude that if the function returns true, it is correct. 如果n =初始数组的大小,我们可以得出结论,如果函数返回true,则它是正确的。
If this proof is not correct, please let me know. 如果此证明不正确,请告诉我。 I will edit my post again if I find proof for the second half.
如果我找到下半场的证据,我会再次编辑我的帖子。
One solution is to use array_reduce
and array_diff
to speculatively assign employees to orders. 一种解决方案是使用
array_reduce
和array_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
Sorting the array first avoids the problem of "assigning" a worker to an order who MUST be assigned to a later order. 首先对数组进行排序可以避免将工作人员“分配”给必须分配给以后订单的订单的问题。
Your main issue is about the algorithm. 您的主要问题是关于算法。 As discussed, the language is of secondary importance.
如上所述,该语言具有次要意义。
What you want is to 你想要的是什么
check if each order can be assigned one employee and each employee assigned one or no order
检查每个订单是否可以分配一个员工,每个员工是否分配了一个订单
You can draw it like a graph: 您可以像图表一样绘制它:
So you want to remove all necessary links so that 所以你想要删除所有必要的链接
If you succeed, you have a solution and want the algorithm to return true
. 如果您成功,您有一个解决方案,并希望算法返回
true
。 Otherwise, it should return false
. 否则,它应该返回
false
。
EDIT: J. Quick found an incredibly simple implementation that works. 编辑:J。Quick发现一个非常简单的实现工作。 I would love to get a proof of it or a reference of where he found it though.
我很想得到它的证明或参考他发现它的地方。
So I explain it here: 所以我在这里解释一下:
true
true
false
false
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;
}
You can run it like that: 你可以像这样运行它:
const orders = [
[0,1,2],
[0,1,2],
[3],
[3]
];
console.log(areAllOrdersFulfilled(orders));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.