【问题标题】:Is it possible to implement delayed (non-strict) arrays on C?是否可以在 C 上实现延迟(非严格)数组?
【发布时间】:2014-01-19 22:48:01
【问题描述】:

我一直在探索延迟数组的想法。如果我理解正确,它们只是像数组一样使用的函数。因此,例如,在 JavaScript 中:

// Brief implementation:
array = function(values){
    return function(i){
        if (i>=0 && i<values.length)
            return values[i];
        else
            throw "Out of bound";
    }
};
set = function(array,index,val){
    return function(i){
        return i === index ? val : array(i);
    }
};

// Using:
my_array = array([10,20,30,40]);
assert(my_array(0) === 10);
assert(my_array(1) === 20);
new_array = set(my_array,0,100);
assert(new_array(0) === 100);

这样做的好处是您可以影响 O(1) 而不是 O(N) 中的每个元素,代价是必须定期摊销它。考虑到它没有被解释,我不知道如何在 C 中实现它,所以它可能需要不断地重新编译访问器。可行吗?

【问题讨论】:

  • 这如何让您影响 O(1) 中的所有元素?此外,就内存分配而言,它非常浪费。我唯一能看到的就是它基本上是写时复制。
  • 我不明白这个延迟数组的概念。 Google 什么也没给我。
  • AFAIK,数组访问也是 O(1),因为基本上发生的一切都是 base + sizeof(type) * n
  • @Viclib:您意识到如果您确实访问所有元素,它仍然是 O(n)。所以这不是 O(1) 与 O(n) 的问题,而是惰性与急切计算的问题。至于如何在 C 中做,嗯,和在 JS 中做的一样:不是直接进入数组,而是在你和它之间放置一个函数。
  • @Viclib:当然它会创建动态分配的中间结构。你认为set 返回的值是什么?

标签: javascript c++ c arrays


【解决方案1】:

如图所示,这不能在 C 中完成,但可以在 C++11 中使用 lambda 表达式完成。等价的程序大致是:

template <typename T>
auto array(const std::initializer_list <T> values)
{
    return [&](size_t i) { return *(values.begin() + i); };
}

template <typename A, typename T>
auto set(A&& array, size_t index, const T& val)
{
    return [&](size_t i) { return i == index ? val : array(i); };
}

int main ()
{
    auto my_array = array({10,20,30,40});
    assert(my_array(0) == 10);
    assert(my_array(1) == 20);
    auto new_array = set(my_array, 0, 100);
    assert(new_array(0) == 100);
}

我没有添加边界检查,这在 lambda 中是不可能的,但可以通过额外的函数调用来实现。在 C++03 中也可以对自定义模板函数对象执行相同的操作,但需要更多代码。

我不是在这里评论这种方法的有用性或效率,我只是展示一种可能的方法,使其类似于给定的 Javascript 示例。

【讨论】:

  • 没有什么要求将这些函数内联编写,因此不需要 lambdas。除非“使代码看起来与给出的 JS 示例相同”是一个要求。示例本身可以很容易地在没有匿名函数的情况下重写,而这正是我们所有人在 C++03 中编写谓词时所做的。
  • 是的,当然,这是我在代码下面写的;我只是想表明与问题中的 JS 代码的相似性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-23
  • 1970-01-01
  • 2020-11-14
相关资源
最近更新 更多