【问题标题】:how to check for array or range length being at least N in Dlang如何在 Dlang 中检查数组或范围长度至少为 N
【发布时间】:2019-04-03 12:59:13
【问题描述】:

对于 N=1,我会使用 std.array : empty 来检查长度是否至少为 N,并避免遍历整个输入。

对于N>1(或全N),D语言的惯用方式是什么?

我尝试使用std.range : take,它“Lazily 最多只占用一个范围的 n 个元素。”。它适用于数组,但不适用于范围(当然,除非我将子范围放入数组中):

#!/usr/bin/env rdmd

module test_ranges;

void main()
{
    import std.container.dlist : DList;
    assert(lengthAtLeast([1, 2, 3], 2) == true);

    // assert(lengthAtLeast(DList!int(1, 2, 3)[], 2) == true);
    /*
test_ranges.d(64): Error: no property length for type Take!(Range)
test_ranges.d(10): Error: template instance `test_ranges.lengthAtLeast!(Range)` error instantiating
Failed: ["/usr/bin/dmd", "-v", "-o-", "test_ranges.d", "-I."]
    */
}

bool lengthAtLeast(R)(R input, size_t n)
{
    import std.range : take;

    return input.take(n).length == n;

    // this makes it work for arrays and ranges alike, but is not nice, is it?
    // import std.array : array;
    // return input.take(n).array.length == n;
}

【问题讨论】:

    标签: d phobos


    【解决方案1】:

    walkLength 做你想做的事:

    bool lengthAtLeast(R)(R input, size_t n)
    {
        import std.range.primitives : walkLength;
        return input.walkLength(n) >= n; // walks upTo n or returns the length if known
    }
    

    【讨论】:

    • walkLength 应该适用于所有范围(输出范围除外,但它们是非常不同的野兽)。由于数组是范围,因此应该涵盖您的所有基础。
    • 来自hasLength doc 我不确定如果给定的范围“有”一个长度,当它想要返回它时它实际上不会花费 O(整个长度)。我认为在某些情况下,它会通过耗尽整个范围来计算!所以理论上可能会有更好的答案。
    • 如果一个范围有length,它将被使用。只有在其他情况下,才会迭代范围以计算元素的数量。
    • 实际上,我想确保所有类型输入的最大时间和空间效率,所以我想知道我使用take(n).array 的方法是否会更好。但是,我的方法中的 .array 可能会导致空间效率低下,因此我可能需要通过更花哨的模板来组合方法。
    • 我已经在每个输入类型的紧密循环中测试了不同的断言 500K 次,整个程序在 multitime 下预编译。对于切片DList@BioTronic 的解决方案比我的快 1.5 倍,对于普通阵列比我的快 2 倍。使用 (R)DMD 2.082.0,没有任何开关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-10
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多