【问题标题】:Appropriate algorithm to replace three nested loops - nested comments替换三个嵌套循环的适当算法 - 嵌套注释
【发布时间】:2014-03-13 14:57:36
【问题描述】:

所以我正在编写一个带有嵌套回复的评论系统。我已经完成了存储和检索部分,最后得到了一组评论对象,每个对象都有一个回复属性,它本身就是一组评论对象。

我允许的最大深度是 3 - 或对回复的回复。

我正在寻找一个适当有效的替代三个嵌套循环来显示 cmets,或者循环通过顶层,然后循环通过他们的回复,然后循环通过他们的回复,因为这是不可扩展的。

好的,所以有人要求我提供一些代码:

class Comment{
    public $replies = array();
    public $content;
}

所以一个评论对象包含一个回复数组,这些回复本身就是评论对象。这深入了三层,所以我有一个顶级 cmets 数组,每个包含一个回复数组,每个回复包含一个回复数组。

我想找到一个比这更好的解决方案,因为我相信它的结果是 O(n^3):

foreach($comments as $c){
    //do some stuff to display the comment here
    foreach($c->replies as $r){
        //do some stuff to display the replies here
        foreach($r->replies as $rr){
            //do some stuff to display replies to replies here
        }
    }
}

【问题讨论】:

  • 为了获得一个合格答案的远程机会,我认为您必须发布一些代码 - 比如那些“三个嵌套循环”的示例.. :)跨度>
  • @davidkonrad - 已修复,请参阅添加的代码。
  • 您的commentsrepliesreplies to replies 是否保存在mysql 表中?如果是,我是否建议使用 JOIN 查询。
  • @Jhn - 我不确定这对我的问题有什么帮助?连接查询不是如何有效循环遍历树数据结构的解决方案...
  • 那么对于您正在寻找的解决方案,您希望整个评论链同时加载到内存中吗?不像是根据请求检索回复的延迟加载。

标签: php algorithm tree


【解决方案1】:

首先,您的代码的运行时间不是O(n^3),而是O(total number of replies),因为它只会遍历所有回复一次(循环不是从1 运行到n,它们是 foreach 循环,它们执行的迭代次数取决于数组的大小)。

没有更好的运行时间来执行这个任务,因为你想对每个回复做一些事情,所以这个任务的下限是O(total number of replies)

我要做的是重写代码并使用递归函数,因为您的代码对更改不是很灵活,如果有一天您决定允许 4 级回复,您将不得不重写此代码代码,而如果您使用递归,则不会。

就像我说的那样,它不会提高性能,而只是一种更好的做法。

【讨论】:

  • 因为理论上可以添加无限数量的 cmets,所以它确实是 O(n^3)。使用 N 是因为我们不知道 cmets 的总数,而且实际上直到我们从数据库中提取它们时我们才知道。
  • @RhodesianHunter 在这种情况下n 是什么?每个评论是否一定有相同数量的回复?不必要。 n 应该代表输入的大小,在这种情况下,它是回复的总数,无论在哪个级别,并且算法在此输入大小的线性时间内运行。
  • 想想像 disqus 这样的评论系统 - 对 0-2 级的任何评论可能有无限数量的回复 - 我们在这种情况下使用 n,因为 n 可以是 0 之间的任何数字 - 无穷大 (理论上)
  • O(n^3) 仅适用于每个 1 级评论包含一个其他评论的数组,然后每个评论都包含所有其他评论的整个数组。最理想的情况是,每个评论应该包含一个仅包含它自己的回复的数组,并且对于第 3 级也是如此。这意味着每个评论/回复应该只在您的评论/回复树中存在一次。这意味着每个只处理一次,所以 O(n)。
  • 当然。递归绝对是要走的路。在某些时候,例如在用户界面方面,或者可能通过一些全局变量/设置,您可以限制回复的深度。在过去的项目中,我在递归函数中使用了一个称为“级别”的参数或其他东西来跟踪我在递归中的深度。
猜你喜欢
  • 2019-01-24
  • 1970-01-01
  • 1970-01-01
  • 2021-08-09
  • 2019-06-06
  • 2021-09-05
  • 1970-01-01
  • 2016-07-14
  • 2018-08-06
相关资源
最近更新 更多