伪代码:递归处理列表中的开始/停止时间

时间:2016-04-18 09:03:16

标签: algorithm recursion profiling pseudocode

这是一个相当模糊的问题。

我有一个脚本执行的开始/停止时间列表,其中可能包括嵌套脚本调用。

| 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。

我试图包裹我的(流感缠绕的)头部是一种伪代码算法,用于逐步或递归通过时间列表以生成时间执行值每一行。

感谢这个问题(或治疗感冒)的任何帮助。 : - )

1 个答案:

答案 0 :(得分:1)

如果所有时间点都不同,则脚本执行时间间隔通过有序树相互关联:给定任何一对脚本执行时间间隔,其中一个严格包含另一个,或者它们根本不重叠。如果您愿意,可以轻松恢复父子关系。

但如果您只关心执行时间,我们甚至不需要! :)有一个非常简单的算法,只需对开始和结束时间进行排序,然后遍历生成的“事件”数组,维护一堆打开的“框架”:

  1. 创建一个(time, scriptID)对数组,并将每个脚本的开始时间和结束时间插入其中(即,将每个脚本插入两对到同一个数组中)。
  2. 按时间排序数组。
  3. 创建一个整数三元组的堆栈,并在其上推送一个(0, 0, 0)条目。 (这只是一个简化以后代码的虚拟条目。)还创建一个数组seen[],每个脚本ID都带有一个布尔标志,所有这些都初始设置为false
  4. 遍历排序的(time, scriptID)对数组:
    • 每当您看到一个(time, scriptID)对以前没有见过的脚本ID时,该脚本就会启动。
      • 设置seen[scriptID] = true
      • 将三重(time, scriptID, 0)推入堆栈。最终组件(最初为0)将用于累计在此脚本的“后代”脚本中花费的总持续时间。
    • 每当您看到之前看过的脚本ID的时间(因为seen[scriptID] == true)时,该脚本就会结束。
      • 从堆栈中弹出顶部(time, scriptID, descendantDuration)三元组(请注意,此三元组中的scriptID应与数组当前索引处的对中的scriptID匹配;如果不匹配,则以某种方式使用“相交”脚本时间盘这与嵌套脚本运行的任何序列都不对应。)
      • 此脚本ID的持续时间(正如您所知)time - startTime[scriptID]
      • 执行时间为duration - descendantDuration
      • 通过将其duration添加到新的堆栈顶部descendantDuration(即第三个)字段,记录此脚本及其后代所花费的时间。
  5. 这就是全部!对于n个脚本执行,这将花费O(n log n)时间,因为排序步骤需要那么长时间(迭代数组并执行堆栈操作只需要O(n))。空间使用是O(n)。