我找到了解决方案,请参阅下面的答案和/或Github Gist, which has newer optimizations。
我有一系列的信用卡费用和一批总数...有时数量的SUM()=批量,因此很容易分组到批次,我们可以检查有关的交易当天存入支票账户。
有时,适当的金额用于这些费用的一部分,其中一个或多个在第二天进行批处理。 你能以编程方式解决这个问题吗?这是我的authorize.net批量会计,很糟糕,所以我正在为我的簿记员制作一个工具。
+------------+--------+
| transId | amount |
+------------+--------+
| 2863996511 | 154.00 |
| 2863992361 | 762.20 |
| 2863898975 | 49.00 |
| 2863894564 | 5.44 |
| 2863879671 | 10.88 |
| 2863858891 | 209.00 |
| 2863856334 | 148.00 |
| 2863367273 | -25.01 |
+------------+--------+
当天的批次总额为1302.63美元。正如经常发生的那样,电荷没有在该批次中结束,因此批次是阵列中电荷总和的一部分。在这种情况下,10.88美元的费用是在第二天的批次。这一点伪代码可以通过两个嵌套的for循环来捕获它:
for( $skipdx=0; $skipdx<$size; $skipdx++){
$total=0;
for( $idx=0; $idx<$size; $idx++){
if($idx!=$skipdx){
$total+=$charges[$idx]['amount'];
$thisBatch[]=$charges[$idx]['transId'];
}
if( abs($total-$batch['total']) < .04 ) {
echo "sum of charges matches $date batch total: $$total (line: ". __LINE__ .")\n";
$foundIt=TRUE;
break;
}
}
if($foundIt==TRUE)
break;
}
如何动态选择搜索未添加TWO的费用?那么三个?我可以看到,如果$skipdx
省略了一个电荷,那么跳过两个电荷会添加一个skip2dx
嵌套循环。如果仍未找到,skip3dx
将成为第3级嵌套。
我通常非常擅长算法直到递归然后我变得愚蠢。
答案 0 :(得分:0)
它来找我!递归的“当前层”执行此操作:
工作代码(Github has newer optimizations也是):
$charges=Array(
'2863996511' => 154.00 ,'2863879671' => 10.88
,'2863992361' => 762.20 ,'2863858891' => 209.00
,'2863898975' => 49.00 ,'2863856334' => 148.00
,'2863894564' => 5.44 ,'2863367273' => -25.01
); print_r($charges);
$targets=Array(1302.63, 1327.64, 1322.20 );
foreach( $targets as $batch ) {
printf( "We seek combination of transIds to = $%-7.2f\n", $batch);
$answer=reco( $batch, $charges );
if( is_array($answer) )
echo eval( "return ".implode("+",$answer).";" )."\nWIN!\n";
else
echo "Bust!\n";
}
function reco( $target, $arr ){
if( count($arr) < 2 )
return FALSE;
$killid='';
$sum = eval( "return ".implode("+",$arr).";" );
foreach( $arr as $id=>$amt ){
if( abs($sum-$target-$amt) < .01 ) {
$killid=$id;
break;
}
}
if( strlen($killid) > 1 ) {
echo ". omit $killid : ".$arr[$killid]."\n";
unset($arr[$killid]);
return $arr;
}
foreach( $arr as $id=>$amt ){
$tmp=$arr;
unset($tmp[$id]);
$rtn = reco( $target, $tmp );
if( is_array($rtn) ) {
echo ".. omit $id : ".$arr[$id]."\n";
return $rtn;
}
}
return FALSE;
}
输出:
We seek combination of transIds to = $1302.63
. omit 2863879671 : 10.88
1302.63
WIN!
We seek combination of transIds to = $1327.64
. omit 2863367273 : -25.01
.. omit 2863879671 : 10.88
1327.64
WIN!
We seek combination of transIds to = $1322.20
. omit 2863367273 : -25.01
.. omit 2863879671 : 10.88
.. omit 2863894564 : 5.44
1322.2
WIN!
表现不是一个很大的问题;到大约一秒钟处理的第三级递归。
答案 1 :(得分:0)