(已解决) 关于 A.news(X;xi:Fi,…) 中的参数 X
大佬们,早上好!
如下所示,有这么一个需求,需要把表 1 中的每一行按照表 2 中字段 2 的值按顺序拆分成多行,得到结果:
比如,表 1 中的第 1 行的总时长 223.4,根据表 2 中的第 2 列按顺序拆分如下:
223.4=A:120+B:75+C:28.44
此时表 2 中的 C 拆分出去 28.44,还剩下 61.56 继续进入表 1 中第 2 行的拆分:
67.2=C:61.56+D:5.64
D 还剩下 90-5.64=84.36 继续进入下一个拆分….
最直接的方法就是循环,比如在 IDE 里的写法如下,为了方便我把表 1 变成了只有一个数:
用 A.()方法循环之后,可以看到 A4 的结果,以及表 2(R) 变化之后的结果:
这样的结果符合预期。
换成 A.news() 之后,结果就变得凌乱了,A5 格和表 R 变化之后的结果如下:
可以看到,似乎在 news 里 R 的结果变化了好几次,而最外层的 A 实际上只有一行。按我的理解 A.news()也是循环函数,一参中括号内容用逗号隔开,返回的是最后一个逗号之后的值,应该跟 A.conj() 这样的循环函数结果一样。
恳请大佬们有空时帮忙看看,谢谢! 数据如下,可以直接复制使用,A4 格和 A5 格不能同时执行,注释掉其中一个,再观察执行结果:
A | B | |
1 | =A=new@t(223.44: 总时长) | |
2 | =R=create(段名, 时长) .record([ "A",120,"B",75,"C",90, "D",90,"E",60 ]) | |
3 | ||
4 | /=A.conj( ( V = #1, C = 0, X = R.select@tc((C+=#2) <= V ), S=X.sum(#2), R.delete(X).modify(1,C-V:#2), X.derive().record([R.#1,V-S],0))) | V 表示序表 A 中的字段值 C 表示一个累计值,每次循环开始时为 0 X 表示从 R 表中选出 #2 的累计和小于等于 A 表中#1 的记录 S 表示选出的记录求和 此处从 R 表中删除选出的记录 X,并把第一行的 #2 字段值改成 C-V 此处表示选出的记录 X 中再加上一条时长不够的记录 |
5 | =A.news( ( V = #1, C = 0, X = R.select@tc((C+=#2)<=V), S=X.sum(#2), R.delete(X).modify(1,C-V:#2), X.derive().record([R.#1,V-S],0) ) ;~).derive@x() |
A.news 为了自动生成结果集的字段名会先用第一条记录算一下序列表达式 X,因为这个例子的 X 里用了很多修改操作,导致结果不对。
现把这步去掉了,可以更新下开源代码试用。
谢谢大佬🙏
其实,帖子里的这个案例虽然简单,但在实战中经常碰到,是比较常见的 FIFO,先进先出的案例。
常规的解法,就是这样无脑式地循环,一行一行去比对,这种时间复杂度比较高 O(m×n)。
VBA 也是这样双重循环,无非就是设定一个条件在 do..loop 的时候提前跳出来 exit do。
我也不会其它的算法,所以,能否恳请大佬有空有闲情的时候指导一下,这种先进先出的案例有没有高效的解法?