nzynzynzy

nzynzynzy

🏢  Technical Consultant
V2EX 第 444393 号会员,加入于 2019-10-02 13:26:29 +08:00
今日活跃度排名 3653
1 G 31 S 50 B
除了程序员论坛,V2也是一个很折叠的社群,多看少说。
根据 nzynzynzy 的设置,主题列表被隐藏
二手交易 相关的信息,包括已关闭的交易,不会被隐藏
nzynzynzy 最近回复了
@zizon 对的无论 m 还是 n 都是有序的。不同冲销策略确实会导致冲销单据的范围不一定,但是余额是一定的因为余额是 transaction 的累加,和进出无关。
@Motorola3 是的。这是一个例子,实际上可能增增减减数额不会这样完全一致,可能是 100 ,-98 ,110 ,-9.98 这样。
这个情境里不仅销售会减小余额,对余额直接操作也会。而目的是寻找销售对应的余额操作(可能增加、减少),减少余额的操作不用考虑找对应。
@xuanbg 这个是关于账户的操作就比较敏感一点,用户看不见对应的、没办法核查就感到不放心。而且当时牛 p 吹出去了就做了吧虽然难度增加了。
@Chad0000 #15 而且你的例子中假设是 invoice 是可以 pending 状态先进来等待付款,和我的情况有差别,我的更像是进来时候实时判断钱够不够,不够这笔就废止了。我觉得老哥说的 cumsum 是有道理的,而且是正负都存在的 cumsum 。

这个就变成了:cumsum 的数组中找值大于 invoice 的情况,其中最靠队尾的、值大于等于 invoice 的一个或者一群值中最靠前的一个。累死我了这个描述。。。
@NessajCN #12 多谢这个还真的很类似!我感觉余额会过期是一种类似的情况,都是有序的先进先出地消耗,我继续去读一下
@Chad0000 #15 原理有点类似,或者你可以理解为预存/预支 + 购买,而且这个购买的时候要找到对应的预存/预支记录,而且预存/预支是有可能像我描述的可能性 A 这样被第一个记录拦截住,而后面其实还有预支。理想情况是能读取到第五张单据

@NoOneNoBody #13 谢谢,cumsum 确实是这个问题目前最贴切的描述,就是贪婪版的 cumsum ,我去朝着这个方向再探一探

也欢迎其他朋友继续看看!
确实这个东西昨天让我有点心烦意乱的,我打了个草稿放在 V2 然后今天发了,可能真的懂得只有我。

=============================
然后还有一个规则就是“贪婪”先进先出地消耗 JNL ,耗完就停止,举个例子

刚开始余额是 0
----
操作余额#JNL001 ,金额 100
操作余额#JNL002 ,金额-100
操作余额#JNL003 ,金额 100
操作余额#JNL004 ,金额-100
操作余额#JNL005 ,金额 130
销售 INV001 ,金额 100=>操作核销掉 JNL001-004 全部余额,因为他们叠加起来余额是 0 ,然后核销掉 JNL005 的 100 元,剩 30 元
-----
操作余额#JNL006 ,金额 100
这时候发生交易 INV002 ,金额 130 ,此时需要记录 INV002 的来源:
JNL005 ,金额 30 ,核销 30 ,余额 0 ,
JNL006 ,金额 100 ,核销 100 ,余额 0

情况大概就是这么个情况,看看还有什么没讲明白

=============================

@zizon #3
@NoOneNoBody #4
@RecursiveG #5
@Chad0000 #6
@rekulas #7
@wingor2015 #8

烦请各位如果有思路分享一下,有兴趣也可以插眼回来看
感谢各位耐心阅读。

比如以下事件按顺序发生

刚开始余额是 0
==============
操作余额#JNL001 ,金额 100
操作余额#JNL002 ,金额-100
操作余额#JNL003 ,金额 100
操作余额#JNL004 ,金额-100
操作余额#JNL005 ,金额 130
===============
截至目前账户余额是 130 元,此时发生了一单交易 INV001 ,价值 100 元
这一单需说明“这 100 块是从哪些余额操作中来的”,这时候目前面临无数种算法列举 3 种可能性

可能性 A:先进先出,够用就停
INV001 的 100 元来自 JNL001

可能性 B:先进先出,尽可能地记录
INV001 的 100 元来自 JNL001-JNL005 的叠加
JNL001 ,金额 100 ,核销 100 ,余额 0
JNL002 ,金额-100 ,核销-100 ,余额 0
JNL003 ,金额 100 ,核销 100 ,余额 0
JNL004 ,金额-100 ,核销-100 ,余额 0
JNL005 ,金额 130 ,核销 100 ,余额 30

可能性 C:
选一个够用的最大的,即 JNL005 去核销,其他无视

这个例子中追求的算法是以上的 B ,即尽可能记录 INV001 的来源
@ivvei #1 叫发生没什么问题。这个是我抽象的结果,就是打个比方。用户希望通过一笔消费能看到这笔能对应上几笔发生。

这个 transaction 和 invoice 不是一一对应的,你可以想象为客户既可以消费也可以存取,存取并不是指定消费的。

我疏漏了一些描述:
- 就是一顿存取之后,只有一笔 invoice ,不会是多笔。
- 没用到的单子就会自动结转等待下一次使用。

这个数据,算法希望对应的结果应该是

JNL001 ,金额 100 ,使用 100 ,余额 0
JNL002 ,金额-100 ,使用-100 ,余额 0
JNL003 ,金额 100 ,使用 100 ,余额 0
JNL004 ,金额-100 ,使用-100 ,余额 0
JNL005 ,金额 130 ,使用 100 ,余额 30
关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3133 人在线   最高记录 6679   ·     Select Language
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.8.5 · 14ms · UTC 15:02 · PVG 23:02 · LAX 08:02 · JFK 11:02
Developed with CodeLauncher
♥ Do have faith in what you're doing.