【问题标题】:Is it better to check if all elements are equal in an array or a vector if the number of elements is already known?如果元素的数量已知,最好检查数组或向量中的所有元素是否相等?
【发布时间】:2017-12-01 23:13:30
【问题描述】:

如果您已经知道要比较的元素数量(在我的例子中是 5 个),使用std::arraystd::vector 更好吗?

for(int i=1; i<a.size(); i++)
   if(a[0] != a[i]){
      std::cout << "One or more elements are not equal" << std::endl;
      break;
   }
}

for(int i=1; i<myvector.size(); i++)
   if(myvector[0] != myvector[i]){
      std::cout << "One or more elements are not equal" << std::endl;
      break;
   }
}

唯一的区别是一个使用std::array,另一个使用std::vector,但是如果您知道元素的具体数量,在这种情况下是否有理由使用另一个?

【问题讨论】:

  • 这两种方法都适用于std::vectorstd::array。您的示例似乎不支持您的问题。
  • @FrançoisAndrieux 是的,对不起。我编辑了std::vector 示例,使其成为for 循环。
  • 那么现在这两个代码示例有什么区别呢?不清楚你在问什么
  • @UnholySheep 我的问题是,如果我事先知道元素的数量,使用std::arraystd::vector 进行比较是否更好。除了一个是std::array 和一个是std::vector 之外没有其他区别。
  • 更好是什么意思?

标签: c++ arrays vector equality


【解决方案1】:

既然eran列出了std::array的优点,那我就列出std::vector的优点。

  1. 移动速度更快。 std::vector 的移动构造函数/赋值运算符只不过是几个指针的副本(O(1) 操作)。移动 std::array 需要移动每个单独的元素(O(n) 操作)。
  2. 不太可能导致堆栈溢出。无论std::vector 有多少元素,它只会在堆栈上保留很小的空间。 std::array 的元素是对象本身的一部分,所以如果它在堆栈上,那么它的所有元素都在堆栈上。如您所说,如果您只有 5 个元素,这可能不是问题。
  3. 它提供了对何时构造和销毁对象的更多控制。 std::array 必须在初始化时创建其所有实例。当您的类型没有默认构造函数时,这可能特别不方便,因为您需要单独输入所有初始化。使用std::vector,您可以在循环中或在闲暇时进行构造。

【讨论】:

  • 还提供了对何时构造和销毁对象的更多控制。 std::array 必须在初始化时创建其所有实例
  • @Curious:好电话。已添加。
  • 同时,您还可以提及,如果数组超出一定大小(可能比溢出堆栈的大小小得多),编译器无论如何都会生成一个循环,因为展开会生成太多代码。
【解决方案2】:

如果您在编译时知道大小,请使用std::array。它有两个优点:

  1. 没有动态分配(因此,也没有指针取消引用访问内部数组)。
  2. size() 的值在编译时是已知的,使编译器更容易优化。例如,一个只有 5 次迭代的短循环可能会被展开,从而消除条件分支。

顺便说一句,您所做的两次检查相似的编辑使您的问题更加集中,这很好,但惯用的 C++ 建议最少使用显式循环。所以std::adjacent_find 更好,可以在两个容器上使用。

【讨论】:

  • 我以前从未使用过std::adjacent_find,但在关于std::vector 的元素比较的问题中看到了它,并认为它是一个仅适用于std::vector 的功能,但我会阅读它并从循环到std::adjacent_find
  • @Javia1492 标准算法通常在迭代器上运行,并不关心实际的容器类型。每个算法对其接受的迭代器都有要求,只要您的容器的迭代器满足这些要求,该算法就可以与您的容器一起使用。这对于用户实现的容器也是如此,前提是您的容器的迭代器已正确实现。见Iterator concept
  • 无动态分配 ...这也可能是std::array缺点:如果您的数据没有,它可能会导致堆栈溢出t 适合堆栈空间。堆栈通常限制在编译时配置的固定大小(例如,MSVC 使用的默认大小仅为 1 MiB)。
  • @Javia1492 std::vector is a sequence container that encapsulates dynamic size arrays 这里不需要“动态大小数组”。
  • 但惯用的 C++ 建议尽量少使用显式循环 IMO 并非如此,这完全取决于用户的舒适度。基于范围的 for 循环比大多数 for_each 方法等工作得更好。对于简单的事情,显式循环通常已经足够好并且是惯用的。对于 istream 输入之类的情况更是如此
猜你喜欢
  • 2013-12-15
  • 1970-01-01
  • 2018-05-13
  • 2015-02-12
  • 2013-03-10
  • 2012-12-16
相关资源
最近更新 更多