二维复杂数组c++

2D complex array in C++

本文关键字:复杂 数组 c++ 二维      更新时间:2023-10-16

我是新的c++编程,所以我需要一个关于二维数组的帮助。是否有可能创建复杂的数组从两个真正的数组与两个for循环?我试图在我的代码中做到这一点,但是……我不知道该怎么做。谢谢你的帮助!这是我的代码::

#include <iostream>
#include <fstream>
#include <complex>
#include <cmath>
using namespace std;
int const BrGr = 15, BrCv = BrGr + 1, BrSat = 24;
//(BrCv=number of nodes,BrSat=number of hours)
int main()
{
    // Every array must be dynamic array.It is a task.Is this correct way?
    auto *Ipot = new double[BrCv - 1][BrSat];
    auto *cosfi = new double[BrCv - 1][BrSat];
    auto *S_pot = new complex<double>[BrCv - 1][BrSat];
    auto *I_inj = new complex<double>[BrCv - 1][BrSat];
    auto *V_cvo = new complex<double>[BrCv][BrSat];
    ifstream reader("Input.txt");
    if (reader.is_open())
    {
        for (int i = 0;i < BrCv - 1;i++)
        {
            for (int j = 0;j < BrSat;j++)
            {
                reader >> Ipot[i][j];
            }
        }
        for (int i = 0;i < BrCv - 1;i++)
        {
            for (int j = 0;j < BrSat;j++)
            {
                reader >> cosfi[i][j];
            }
        }
    }
    else cout << "Error!" << endl;
    reader.close();
    // Here i want to create 2D array of complex numbers -  Is this correct way?
    // Also in same proces i want to calculate a value of S_pot in every node for every hour
    for (int i = 0;i < BrCv - 1;i++)
    {
        for (int j = 0;j < BrSat;j++)
        {
            S_pot[i][j] = complex<double>(Ipot[i][j]*cosfi[i][j],Ipot[i][j]*sqr(1-pow(cosfi[i][j],2)));
        }
    }
    // Here i give a value for V_cvo in nodes for every single hour
    for (int i = 0;i < BrCv;i++)
    {
        for (int j = 0;j < BrSat;j++)
        {
            V_cvo[i][j] = 1;
        }
    }
    // Here i want to calculate a value of I_inj in every node for every hour
    for (int i = 0;i < BrCv - 1;i++)
    {
        for (int j = 0;j < BrSat;j++)
        {
            I_inj[i][j] = conj(S_pot[i][j] / V_cvo[i][j]);
        }
    }
    // Here i want to delete all arrays
    delete[] Ipot, cosfi, S_pot, I_inj, V_cvo;
    system("pause");
    return 0;

注意:我在这些示例中使用double,但您可以用任何类型替换double。

老实说,你可能不想使用2D数组。

在c++中创建二维动态大小的数组是一个多阶段的操作。你不能就这样

double twoDArray [nrRows][nrColumns];

auto twoDArray = new double[nrRows][nrColumns];

这样做有一些错误,但最重要的是行和列不是常量,不是在编译时定义的值。有些编译器允许第一种,但不能保证。我不知道是否有编译器允许第二种

相反,首先创建一个行数组来保存列,然后分别创建每一行的列。恶心。

设置如下:

double * arr[] = new double*[nrRows]; // create rows to point at columns
for (size_t index = 0; index < nrRows; index++)
{
    arr[index] = new double[nrColumns]; // create columns
}

这里是清理

for (size_t index = 0; index < nrRows; index++)
{
    delete[] arr[index]; // delete all columns
}
delete[] arr; // delete rows

对于你的努力,你得到了蹩脚的空间局部性和性能打击(缓存丢失),因为你的许多数组可能在RAM中的任何地方,你得到蹩脚的内存管理问题。一个错误,一个意外的异常,你就会有内存泄漏。

下一个选项具有更好的局部性,因为只有一个大数据数组可以读取,而不是许多,但仍然存在相同的泄漏问题。

double * arr2[] = new double*[nrRows]; // create rows to point at columns
double holder[] = new double[nrRows* nrColumns]; // create all columns at once
for (size_t index = 0; index < nrRows; index++)
{
    arr[index] = &holder[index * nrColumns]; // attach columns to rows
}

和清理:

delete[] arr2;
delete[] holder;

在c++中,除非给出非常,非常令人信服的理由,否则同样的人会选择std::vector而不是动态大小的数组。为什么在SO和整个互联网上被记录得要死,证据是互联网上充斥着被劫持的电脑,提供成堆的垃圾邮件和其他肮脏的东西。

std::vector<std::vector<double>> vec(nrRows, std::vector<double>(nrColumns));

用法与数组用户习惯的完全相同:

vec[i][j] = somevalue;

这实际上没有内存问题,但又回到了蹩脚的位置,因为向量可能在任何地方。

但…!

还有一个更好的方法:使用一维数组并将其包装在一个简单的类中,使其看起来像2D。

template <class TYPE>
class TwoDee
{
private:
    size_t mNrRows;
    size_t mNrColumns;
    vector<TYPE> vec;
public:
    TwoDee(size_t nrRows, size_t nrColumns): 
        mNrRows(nrRows), mNrColumns(nrColumns), vec(mNrRows*mNrColumns)
    {
    }
    TYPE & operator()(size_t row, size_t column)
    {
        return vec[row* mNrColumns + column];
    }
    TYPE operator()(size_t row, size_t column) const
    {
        return vec[row* mNrColumns + column];
    }
};

这个小东西会做你需要一个2D矢量做的大部分事情。你可以复制,可以移动。你想吃什么就吃什么。Jay Leno会做更多。

我直接跳到模板化版本,因为我找不到解释两次类TwoDee的好理由。

构造函数很简单。你给它数组的维度,它就会建立一个漂亮,安全的一维向量。没有混乱,没有大惊小怪,不需要Zayn。

operator()函数接受行和列的索引,做一些简单的算术运算将这些索引转换为单个索引,然后返回对索引值的引用以允许修改,或者返回常量情况下索引值的副本。

如果你觉得你需要额外的安全,添加范围检查。

TYPE & operator()(size_t row, size_t column)
{
    if (row < mNrRows && column < mNrColumns)
    {
        return vec[row* mNrColumns + column];
    }
    throw std::out_of_range("Bad indices");
}

OK。OP是如何使用它的?

TwoDee<complex<double>> spot(BrCv - 1, BrSat);

已创建并准备就绪。然后加载:

for (int i = 0;i < BrCv - 1;i++)
{
    for (int j = 0;j < BrSat;j++)
    {
        Spot(i,j) = complex<double>(7.8*Ipot(i,j),2.3*cosfi(i,j));
    }
}

为基本类型声明动态2D数组与std::complex<T>相同。

参差不齐的数组:

complex<int> **ary = new complex<int>*[sizeY];
//run loop to initialize
for (int i = 0; i < sizeY; ++i) 
{
    ary[i] = new complex<int>[sizeX];
}
//clean up (you could wrap this in a class and write this in its destructor)
for (int i = 0; i < sizeY; ++i) 
{
    delete[] ary[i];
}
delete[] ary;
//access with
ary[i][j];
//assign index with
ary[i][j] = complex<int>(int,int);

它的权重比它需要的要重一些,并且它分配的块比你需要的要多。多维数组只需要一个内存块,而不是每行需要一个内存块。

矩形数组:

complex<int> *ary = new complex<int>[sizeX * sizeY];
//access with:
ary[y*sizeX + x]
//assign with
ary[y*sizeX+x] = complex<int>(int,int);
//clean up
delete[] ary;

只分配一个连续的块是可行的方法(对分配器的影响更小,更好的局部性,等等),但是你必须牺牲干净漂亮的下标