【问题标题】:Does accessing vector elements by reference reduce space complexity in C++?通过引用访问向量元素是否会降低 C++ 中的空间复杂度?
【发布时间】:2020-08-29 04:49:22
【问题描述】:

我有一个简单的 C++ 算法,可以处理来自向量的元素。我通过引用传递我的函数向量,并使用这样的 foreach 循环通过引用访问向量的元素:

vector<int>& gradingStudents(vector<int>& grades) {
    for(int& grade : grades) {
        if (grade > 37) {
            int n = grade % 5;
            if (n >= 3)
                grade += (5 - n);
        }
    }
    return grades;
}

我的问题是,考虑到空间复杂度由辅助空间和输入空间组成,说我的算法的空间复杂度是线性的是否正确(因为输入大小可能会有所不同)?或者空间复杂度是常数,因为输入已经存在于内存中(它只是被引用)并且除了我的临时n变量之外不需要额外的空间?

【问题讨论】:

  • 虽然引用看起来似乎没有占用空间(它们是 Reference 其他东西),但在实现方面这可能是不可能的。编译器可能能够优化 grade 以不占用内存空间(例如通过使用 CPU 寄存器),但其他引用通常作为指针实现,并且指针也需要空间(在典型的 64 位系统上指针通常比 int 值使用 更多 空间)。
  • 话虽如此,在典型的 PC 型系统(包括手机等系统)上,除非您已测量,否则不需要此类微优化前两个问题。由于您修改了向量及其内容,因此您实际上无法选择是否使用引用。
  • 这在很大程度上取决于您如何定义空间复杂度。通常,该术语涵盖所有数据,包括输入数据。在这种情况下,您的算法的空间复杂度是线性。经常使用附加术语辅助空间复杂度,它仅定义算法使用的辅助/临时数据(不包括输入)。在这种情况下,您的算法的辅助空间复杂度是常量

标签: c++ algorithm vector space-complexity


【解决方案1】:

由于您只使用与向量有关的引用,因此您不需要更多内存。你唯一的写法是grade += (5-n),和任何int(或数字类型)一样,这发生在变量当前被寻址的地方——在这种情况下是向量本身。

据我所知,您在这里分配了一个额外的 int,并且没有使用其他“辅助”空间。也许另一个用于引用(如指针),虽然我不确定,因为实现可能使用grades+int_offset 直接访问变量而无需额外的指针。

【讨论】:

    【解决方案2】:

    空间复杂度是常数,因为输入已经存在于内存中(它只是被引用)并且除了我的临时 n 变量之外不需要额外的空间?

    是的。

    时间复杂度为O(grade.size()),空间复杂度为O(1)。

    但是,如果您删除引用,符号 O 或更准确地说,θ 描述的渐近时间复杂度在这里不会改变。因为这只会影响访问每个元素所花费的时间常数。

    另外,复制int 不会花费太多时间,它应该与在基于范围的 for 中没有引用的版本几乎相同(甚至更快,因为引用通常也由指针实现)。

    【讨论】:

    • 在您的第一个“是”回答中,您是否误以为我指的是时间复杂度(而不是空间)?
    猜你喜欢
    • 2016-03-08
    • 2011-06-15
    • 1970-01-01
    • 2019-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多