这是一个相当模糊的问题。
我有一个脚本执行的开始/停止时间列表,其中可能包括嵌套脚本调用。
| script | start | stop | duration | time executing |
| ------ | ----- | ---- | -------------- | ----------------------------------- |
| A | 1 | 8 | 7 i.e. (8-1) | 3 i.e. ((8-1) - (6-2) - (5-4)) |
| ->B | 2 | 6 | 4 i.e. (6-2) | 3 i.e. ((6-2) - (5-4)) |
| ->->C | 4 | 5 | 1 i.e. (5-4) | 1 |
| D | 9 | 10 | 1 i.e. (10-9) | 1 |
| E | 11 | 12 | 1 i.e. (12-11) | 1 |
| F | 9 | 16 | 7 i.e. (16-9) | 5 i.e. ((16-9) - (14-13) - (16-15)) |
| ->G | 13 | 14 | 4 i.e. (14-13) | 1 i.e. (14-13) |
| ->H | 15 | 16 | 1 i.e. (15-14) | 1 i.e. (16-15) |
持续时间是脚本花费的总时间。 执行时间是在脚本中花费的时间,但不在下标中。
所以A调用B和B调用C.C取1个滴答,B取4但执行时间仅为3,A取7个滴答,但执行时间为3。 F调用G然后调用H,因此需要7个滴答,但执行时间仅为5。
我试图包裹我的(流感缠绕的)头部是一种伪代码算法,用于逐步或递归通过时间列表以生成时间执行值每一行。
感谢这个问题(或治疗感冒)的任何帮助。 : - )
答案 0 :(得分:1)
如果所有时间点都不同,则脚本执行时间间隔通过有序树相互关联:给定任何一对脚本执行时间间隔,其中一个严格包含另一个,或者它们根本不重叠。如果您愿意,可以轻松恢复父子关系。
但如果您只关心执行时间,我们甚至不需要! :)有一个非常简单的算法,只需对开始和结束时间进行排序,然后遍历生成的“事件”数组,维护一堆打开的“框架”:
(time, scriptID)
对数组,并将每个脚本的开始时间和结束时间插入其中(即,将每个脚本插入两对到同一个数组中)。(0, 0, 0)
条目。 (这只是一个简化以后代码的虚拟条目。)还创建一个数组seen[]
,每个脚本ID都带有一个布尔标志,所有这些都初始设置为false
。(time, scriptID)
对数组:
(time, scriptID)
对以前没有见过的脚本ID时,该脚本就会启动。
seen[scriptID] = true
。(time, scriptID, 0)
推入堆栈。最终组件(最初为0)将用于累计在此脚本的“后代”脚本中花费的总持续时间。seen[scriptID] == true
)时,该脚本就会结束。
(time, scriptID, descendantDuration)
三元组(请注意,此三元组中的scriptID应与数组当前索引处的对中的scriptID匹配;如果不匹配,则以某种方式使用“相交”脚本时间盘这与嵌套脚本运行的任何序列都不对应。)time - startTime[scriptID]
。duration - descendantDuration
。duration
添加到新的堆栈顶部descendantDuration
(即第三个)字段,记录此脚本及其后代所花费的时间。这就是全部!对于n个脚本执行,这将花费O(n log n)时间,因为排序步骤需要那么长时间(迭代数组并执行堆栈操作只需要O(n))。空间使用是O(n)。