【问题标题】:Multi-dimensional dynamic arrays in classes in C++C++类中的多维动态数组
【发布时间】:2013-04-29 19:06:22
【问题描述】:

我是 C++ 的相对初学者。我正在研究与预测房地产财务相关的模型,但在设置数据结构时遇到了一些问题。

一些背景知识 - 我正在尝试执行的特定任务是为关键数据结构设置类变量 - 一种称为 PropFinance 的结构。这个结构将包含我关于给定属性的所有关键信息(包含它们集合中每个属性的迭代),包括对未来性能的预测。传递给程序的两个主要参数是(适用于所有要评估的属性) (1)迭代次数(Iterations)——我们要生成多少次预测(随机迭代) (2) 预测长度 (NumofPeriods) - 我们要预测多少个周期

PropFinance 类中有 79 个变量,其中包含属性详细信息。一个简单的例子——费用。对于费用以及我的许多类似变量,我需要创建一个双精度的 3D 数组 - 每次迭代一个维度,每个预测期一个维度。所以理想情况下,我会有一个变量用于:

class PropFinance {
    double Expenses[Iterations][NumofPeriods];
}

但是,我在编译时不知道 Iterations 和 NumofPeriods。我确实知道这两个变量在运行时开始时的值(并且它们对于当前程序执行的所有迭代/属性都是恒定的)

我的问题是如何在程序运行时动态更新这些数组的大小?根据我对本网站和其他网站的研究,似乎实现此目的的两种主要方法是

(1) 使用 (2)在类定义中使用指针,然后使用new和delete来管理

但即使有这两个选项,我也不确定它是否适用于第三维度(我看到的所有示例都只需要一个维度来动态调整大小)。有人可以发布一个口头解释或(更好)一个简单的代码示例,说明这将如何在上面的(1)或(2)中工作?任何关于哪个选项更可取的指导将不胜感激(但不想开始“什么更好”的辩论)。当数组的大小将不断变化时,似乎 vector 更合适,这里不是这种情况......

此模型的整体速度至关重要,随着我们扩大迭代次数和属性,事情会迅速变大 - 所以我想尽可能高效地做事。

对不起,我没有发布代码 - 如果人们无法从上面看出我在问什么,我可以尝试将一些东西放在一起。

【问题讨论】:

    标签: c++ class vector new-operator dynamic-arrays


    【解决方案1】:

    惯用的解决方案是避免 C 数组的直接堆分配,并更喜欢像 std::vector 这样的 STL 容器,它以高效、可移植的方式自动处理大小调整、迭代和元素访问。我强烈推荐 Scott Meyers 的 Effective STL,它讨论了每个容器对不同应用程序的适用性 - 插入/删除/检索复杂性保证等。

    【讨论】:

    • 谢谢!我想澄清一下,vector 在这里是一个有效的选择——如果我预先声明了这些数组(忽略编译时间信息问题),总体而言,这不会比数千次动态调整数组大小快多少?如果我预测 180 个周期和 25 次迭代(平均大小的运行),那么我将有效地重新调整数组大小 4,500 次。这两种选择之间没有太大的性能差异吗?为我的无知问题道歉 - 我知道在“预先调整大小”的情况下,我仍然需要完成 4,500 个作业,所以可能不会慢很多?
    • 只有您知道周期和迭代次数才能使用 std::vector::reserve(size_t) 预分配向量。此函数将容器的容量设置为所需的数字,因此当您执行 push_back 时可以避免重新分配。
    【解决方案2】:

    如果您需要超过 2 个维度(3、4、5 等)。我知道的最简单的解决方案是使用 boost 提供的 multi_array。

    如果只需要二维数组,请使用向量

    std::vector<std::vector<double> >  Expenses;
    

    既然你是初学者,最好从c++提供的高级组件入手,即使你熟悉c++,你也应该坚持那些高级组件。c++的基本元素在你需要开发的时候使用一些基础设施(向量、列表、智能指针、线程等)。

    #include <iostream>
    #include <vector>
    
    int main()
    {
      std::vector<std::vector<double> > expenses[10]; //contains 10 std::vector<double>
      expenses[0].push_back(100);
    
      std::cout<<expenses[0][0]<<std::endl;
    
      expenses.push_back(std::vector<double>()); //now expenses has 11 std::vector<double>
    
      return 0;
    }
    

    how to use vector

    multi array

    【讨论】:

    • 感谢您的快速回复 - 听起来矢量是现在要走的路(除非我超越二维)。我将研究我的解决方案并稍后发布一些代码。澄清一下 - 一旦我声明了向量,我就使用 push_back 来分配它们?
    【解决方案3】:

    我认为你在处理面向对象编程方面是错误的。

    而不是拥有一个大师班PropFinance,其中包含多维数组中的所有内容。你有没有考虑过像Iteration 这样有多个Period 的类,比如

    class Iteration  
    {
      std::vector<Period­> _periods;  
    }
    
    class Period
    {
    public:
      double Expense;
    }
    

    然后当您添加更多维度时,您可以创建超类PropFinance

    class PropFinance
    {
      std::vector<Iteration> _iterations;
    }
    

    这使得一切都更易于管理,而不是深度嵌套的数组 [][][][]。根据经验,只要您有多个维度数组,请考虑创建包含另一个维度的子类。

    【讨论】:

      猜你喜欢
      • 2012-02-02
      • 1970-01-01
      • 2018-05-16
      • 2011-02-16
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      • 2018-05-19
      • 1970-01-01
      相关资源
      最近更新 更多