Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 大范围连续整数的数据结构?_Python_Algorithm_Tree_Computer Science - Fatal编程技术网

Python 大范围连续整数的数据结构?

Python 大范围连续整数的数据结构?,python,algorithm,tree,computer-science,Python,Algorithm,Tree,Computer Science,假设内存中有一大范围的连续整数,每个整数只属于一个类别。两个操作必须是O(logn):将一个范围从一个类别移动到另一个类别,并查找给定范围的类别计数 我敢肯定,如果第一个操作得到正确的实现,第二个操作就很容易解决了 每个整数从一个类别开始,所以我从一组平衡的BST开始。将子树从一个BST移动到另一个BST(例如,将一个范围移动到另一个类别)的运行时相当于合并两个BST,即O(n1*n2)[] 这太慢了(在python中,C不是一个选项),我无法找到一种方法来利用数据的固有结构来创建一个高效的BS

假设内存中有一大范围的连续整数,每个整数只属于一个类别。两个操作必须是O(logn):将一个范围从一个类别移动到另一个类别,并查找给定范围的类别计数

我敢肯定,如果第一个操作得到正确的实现,第二个操作就很容易解决了

每个整数从一个类别开始,所以我从一组平衡的BST开始。将子树从一个BST移动到另一个BST(例如,将一个范围移动到另一个类别)的运行时相当于合并两个BST,即O(n1*n2)[]

这太慢了(在python中,C不是一个选项),我无法找到一种方法来利用数据的固有结构来创建一个高效的BST合并操作

我现在看的是AVL、红黑和区间树、二进制堆和treap。比较它们的属性是压倒性的。我应该使用哪种结构

编辑(问题澄清):我可以灵活地存储这些值并创建数据结构。我对如何接收来自另一个应用程序的输入缺乏灵活性,如下所示:
CATEGORY(cat3,I,J)
。我当前的解决方案为范围内的每个整数创建一个带有节点的树。这对于我的数据集的大小来说太慢了,所以如果有更好的方法,我很乐意重新设计


任何给定的请求都可以将任何可能的整数范围移动到任何类别中。换句话说,范围在
CATEGORY(cat1,1,10)
之后是
CATEGORY(cat3,5,15)
的意义上是重叠的,但在任何给定时间,每个整数都将恰好位于一个类别中,这一意义上是不重叠的。

您可以拥有以下形式的普通python字典

1 : { "stop" : 5, "category" : "C1"},
6 : { "stop" : 19, "category" : "C23"},
etc
这里的键是范围的起点,值包含范围的终点以及该范围所属的类别

因为字典有固定的访问项目的时间,所以您可以编写一些代码,轻松有效地将一个范围移动到另一个类别:在最坏的情况下,如果您的范围将以前的范围拆分为两个或更多个,您将不得不以某种方式重新构造字典。例如,如果要将(4,8)的范围指定给另一个类别,则最终将得到:

1 : { "stop" : 3, "category" : "C1"},
4 : { "stop" : 8, "category" : "new category"},
9 : { "stop" : 19, "category" : "C23"},
etc
查找类别计数很简单,只需在固定时间内收集所有所需的范围并计算类别


编辑:要成功找到最低(最高)键以开始执行计算/更改,还需要一个包含所有已排序键的普通python列表,以及对分模块。这将有助于在列表中定位索引,以O(logn)时间“放置”范围的开始,然后所有操作都可以在固定时间内完成,除了将新键插入列表所需的O(n)时间(左半部分)。

据我所知,您有一个范围[a,B]和表单查询-

  • 将特定范围指定给类别
  • 徖。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。 ............................................................... 等等

    叶节点将具有范围(1:2,2:3,…)

    您可以为每个节点分配一个值“category”,并给定一个间隔,遍历适当划分间隔的树(例如,对于2500到4500,按2500:3000和3001:4500进行划分,并在两个方向上继续,直到找到具有匹配范围的节点)

    现在一件有趣的事情是在需要时更新节点的子节点。例如,在执行1 5000 C5555之类的作业时,不要立即更新子级。这就是所谓的延迟传播,您可以在这里了解更多信息()

    现在是查询部分。如果类别的数量非常少,您可以在每个节点维护一个频率表,并在需要时更新范围,否则,您将不得不从一个叶遍历到另一个节点,计数和复杂性将变为O(n)

    我认为可能存在更好的查询解决方案。我想不起来了

    更新 让我们举一个小例子

    范围[1,8]

    允许的类别{C1,C2}

            1:8
         1:4         5:8
         1:2  3:4      5:6    7:8
     1:1 2:2 3:3 4:4  5:5 6:6 7:7 8:8
    
    每个节点将有3个字段[类别、类别计数[],子项更新\u必需=false]

    1 5 C1

    查询将被分割,节点1:4的类别将设置为C1,子项更新所需项将设置为true,其子项现在不会更新(请记住仅在需要或延迟传播时更新)。节点5:5的类别也将设置为C1

    3 4 C2


    查询将沿着树向3:4传播(在达到3:4的过程中,1:2和3:4的类别将更新为C1,1:4的子项更新所需将设置为false,1:2和3:4的子项更新所需将设置为true),现在将根据当前需求将3:4的类别更新为C2。接下来,它将为其子级的未来更新(在本例中已设置)设置3:4的children\u update required为true。

    您可以非常轻松地在连续整数数组上构建树结构,这将有助于使用常量因子。首先将序列重新编号为从0开始,并计算出大于序列范围的二次幂中的最小幂

    现在考虑从0到7的整数构成的树,它可以保持为四个数组,每个数组都是水平的。

                (all)
         0-3      4-7
       0-1 2-3  4-5   6-7
     0 1  2  3  4  5  6   7
    
    给定一个数字和一个级别,我可以在数组中找到该级别的偏移量,只需根据级别将数字向右移动一个量即可

    在每个元素中,我可以放置一个标记,表示“mixed”,或者为树节点上或节点下的每个元素提供类别。我可以通过沿着从树的根到叶子的路径,在我离开时立即停止,来确定节点属于哪一类 1 5000 C5555
                       1000:5000
                          |
                 ---------------------
                 |                   |
               1000:3000         3001:5000
                |                    |
        ----------------      --------------------
       |               |      |                  |
     1000:2000     2001:3000   3001:4000       4001:5000
    
            1:8
         1:4         5:8
         1:2  3:4      5:6    7:8
     1:1 2:2 3:3 4:4  5:5 6:6 7:7 8:8
    
                (all)
         0-3      4-7
       0-1 2-3  4-5   6-7
     0 1  2  3  4  5  6   7
    
    0:cat1 200:cat2 500: cat0 700:cat6 800:cat1