看到这个题目大家可能会一头雾水,本人表达能力有限,无法用简单语言描述该算法,标题凑合一下呗。工作后才发现,处理很多生活中业务问题就是在,就像再处理数学题。
用一个案例和大家描述一下吧。总得来说就是总数想等的情况下,如何如何将多对多(n对n)的对应关系拆分成一对一(1对1)的关系,java实现。
假设有
三张付款单(单号,金额) 总数300 : (FK01,100) (FK02, 100) (FK03, 100)
两张发票(单号,金额) 总数300 : (FP01, 100),(FP02, 200)。
我们在进行账务核销的时候,通常是一张付款单,对应一直发票金额一致,类似的案例应该还有很多。
方案一(先进先出)
按照先进先出的原则,先拿第一张付款,用第一张发票与他匹配,多还少补,多余的发票用于下一张付款单,多余的付款单去下一张发票的金额补上,直到补全为止,依次类推。
(FK01,FP01, 100)、(FK02,FP02,100)、(FK03,FP02,100)
方案二(按比例拆分、尾差倒挤保证总额一致)
第一步:按比例拆分付款单,倒挤尾差。拆分付款单
(FK01,100,33%) (FK02, 100,33%) (FK03, 100,1-33%-33% )
第二步:按付款单各张单所展的比例拆分,发票金额,余下的付款单金额,尾差倒挤到最后一张发票。
(FK01,100,33%,FP01,33)
(FK01,100,33%,FP02,(100-33)=67)
(FK02,100,33%,FP01,33)
(FK02,100,33%,FP02,(100-33)=67)
(FK03,100,34%,FP01,34)
(FK03,100,34%,FP02,66)
最终付款单总额
FK01 = 33+67=100
FK02 = 33+67=100
FK03 = 34+66=100
最终发票总额
FP01 = 33+33+34 = 100
FP02 = 66+67+67= 200
案例一代码实现:
/**
* 先近先出原则 依次匹配每一单
* 金额溢出分配到下一单, 金额不足从后面一单取出来
*建立每张付款对应每