存储分段功能的数据结构

时间:2018-11-16 20:33:40

标签: database algorithm math data-structures

我想实现以下功能:

f(x) = a0   -inf < x < b0
       a1    b0 <= x < b1
       a2    b1 <= x < b2
       ...
       an    bn-1 <= x < bn
       an+1  bn <= x < +inf

而不是普通的if-else实现。

def func(x):
    if x<b0: return a0
    elif x<b1: return a1
    .....

我是否有更好的数据结构来组织此活动?

此外,在给定两个序列{an},{bn}的情况下,我如何编写一个返回优化的'func(x)'的'元函数'。

2 个答案:

答案 0 :(得分:2)

如果n大,则要减少if条语句的数量。在Python中,这可以通过将数据存储在字典中来完成:

fx = {b0: a0, b1: a1, b2: a2, ..., bn: an, math.inf: an+1}

对于给定的x值,对字典的键值进行二进制搜索。这为您提供了适当的键来使用,然后使用字典本身来获取相关值。如果您的语言不允许inf作为键,则可以将an+1的值与字典分开,也许将二者都保留为2元组。

这将最大测试次数从n减少到log2(n)

在Python中,“元函数”很容易,因为函数是Python中的一类对象。您没有说明首选的语言:请告诉我您是否需要Python中的“元函数”示例。

答案 1 :(得分:0)

可以仅存储a和b的数组。然后,要查找值,可以在b数组中进行二进制搜索,以找到要返回到a数组中的值的索引。

这实际上执行得很好,但是当我不得不为这个词法分析包(https://github.com/mtimmerm/dfalex)实现状态机时,我想出了一种更快的方法来完成此任务,我认为这很酷。

函数的表示形式是按顺序存储在数组中的二叉树,就像我们通常对堆所做的:https://www.geeksforgeeks.org/array-representation-of-binary-heap/

树的根在array[0]中,任何array[i]的左子节点在array[2i+1],而array[i]的右子节点在{{1} }。树的叶子依次是所有array[2i+2](结果)值,每对相邻的a值对之间的内部节点是您切换时的a(参数)值从一个到另一个。

数组中的堆树顺序确保所有b值在末尾连续出现。

这种表示法的好处是您可以使用此函数查找适当的值,这比二进制搜索更简单,更快捷:

a

很抱歉,如果我在python语法上犯了一个错误-这不是我所熟知的语言。

如果您需要构造一个只接受输入值的函数,则可以构建数组表示形式,并调用一个使闭包如下的函数:

def lookup(x, array, num_internal_nodes)
    i=0
    while (i < num_internal_nodes):
        i = i*2 + (1 if x<array[i] else 2)
    return array[i]

首先要构建函数的数组表示形式,只需制作一个大小合适的数组(def makeF(array, num_internal_nodes): def f(x): return lookup(x, array, num_internal_nodes) return f ),然后对树进行预遍历,并填充{{1 }}(叶)和num_internal_nodes*2+1(内部)值。