我可以使用与静态数组具有相同功能的向量吗

Can I use a vector with the same functionality as a static array?

本文关键字:功能 向量 可以使 静态 数组 我可以      更新时间:2023-10-16

只是一个快速的例子:

我计划有一个AVL树数组(正如你想象的那样,作为一项作业,除了数据结构的学生,还有人使用过AVL树吗?)我想知道我是否可以使用一个很好的向量,并利用for(auto I:vect)c++11功能。

我想做的:1.000.000个元素的AVLTree数组,这样我就可以在CONSTANT时间内检查树是否存在(数组位置是否为NULL)

AVLTree_GeeksforGeeks **AVLArray = new (AVLTree_GeeksforGeeks*)[1000000];
for(int i=0; i<1000000; i++){ AVLArray[i] = nullptr; } //init everything to null
//do stuff with AVL trees
//...
if(AVLTree[52000]!=nullptr)
{
     cout << "tree exists!n";
}

是否存在向量的等价项,它将允许我搜索树的恒定时间?我看到的所有例子都使用vector.push_back()和vector.find()进行搜索。

您可以按照Exceptyon:的建议使用std::vector

std::vector<unique_ptr<AVLTree>> trees(1000000);

通过还使用在c++11中实现的智能指针。如果您关心的是动态调整大小,请记住,您可以在创建向量时(通过将其作为构造函数中的参数传递)或通过resize成员保留初始存储量。

如果您关心的是对其对象的随机访问,请放心,运算符[]具有O(1)复杂性。

如果你知道编译时容器的总容量,你也可以考虑使用c++11的std::数组,它为每个功能提供相同的功能,并对其元素提供相同的恒定时间访问。

std::array<unique_ptr<AVLTree>, 1000000> trees;

vector将工作,因为它们有一个过载的operator[],可以保证对第n个元素的恒定时间访问。

但你的代码不清楚:

AVLTree_GeeksforGeeks *AVLArray = new AVLTree_GeeksforGeeks[1000000];
for(int i=0; i<1000000; i++){ AVLArray[i] = nullptr; } //init everything to null

如果设置为nullptr,则需要一个指针。AVLTree_GeeksforGeeks是指针上的typedef吗?我认为情况并非如此,并且存在拼写错误——否则您只需要删除这个typedef定义即可使用std::unique_ptr<TheRealTyp>。所以为了澄清,我想你的代码真的是:

AVLTree_GeeksforGeeks **AVLArray = new (AVLTree_GeeksforGeeks*)[1000000];
for(int i=0; i<1000000; i++){ AVLArray[i] = nullptr; } //init everything to null

在这种情况下,正如建议的那样,您应该使用std::vector<std::unique_ptr<AVLTree_GeeksforGeeks>>,并且您不必将其初始化为nullptr,并且为std::unique_ptr:的直接"测试"更改了无效性测试

std::vector<std::unique_ptr<AVLTree_GeeksforGeeks>> AVLArray(100000);
// Do stuff with AVL trees
if (AVLArray[52000])
{
   cout << "tree exists!n";
}

现在,如何使用std::vector<std::unique_ptr<X>>

  • 在已分配的区域中设置值:AVLArray[5200] = std::unique_ptr(new AVLTree_GeeksforGeeks));
  • 将条目设置为null:AVLArray[5200].reset()
  • 如果你需要添加一些东西(矢量会增长):AVLArray.push_back(std::unique_ptr(new AVLTree_GeeksforGeeks));
  • 要迭代,请使用for (auto& elem: AVLArray)&是强制性的,否则会调用副本构造器,而std::unique_ptr禁止这样做

这里有一个例子:

#include <iostream>
#include <vector>
#include <memory>
// boost
#include <boost/range/algorithm/for_each.hpp>
#include <boost/range/adaptor/filtered.hpp>
class A {};
int main(int argc, char const *argv[])
{
    std::vector<std::unique_ptr<A>> vector;
    vector.resize(10000);
    // Adding some values
    if (!vector[100])
    {
        std::cout << "Adding vector[100]" << std::endl;
        vector[100] = std::unique_ptr<A>(new A);
    }
    if (!vector[1000])
    {
        std::cout << "Adding vector[1000]" << std::endl;
        vector[1000] = std::unique_ptr<A>(new A);
    }
    // Removing one
    if (vector[100])
    {
        std::cout << "Removing vector[100]" << std::endl;
        vector[100].reset();
    }
    std::cout << "Testing element." << std::endl;
    auto printer = [](const std::unique_ptr<A>& elem) { 
            std::cout << "There is an elem !" << std::endl; };
    // use auto& otherwise use unique_ptr(const unique_ptr&) that has been
    // deleted)
    for (auto& elem: vector) 
    {   
        if (elem)
        {
            printer(elem);
        }
    }
    std::cout << "for_each element with filtering." << std::endl;
    auto is_null = [](const std::unique_ptr<A>& elem) { return (bool) elem; };
    // Just because I move boost range !
    boost::for_each(vector | boost::adaptors::filtered(is_null), printer);
    std::cout << "end !" << std::endl;

    return 0;
}