C ++中的2D复杂数组 [英] 2D complex array in C++

查看:70
本文介绍了C ++中的2D复杂数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是C ++编程的新手,所以我需要有关2D数组的帮助。我可以尝试在我的代码中使用两个for循环从两个真实的数组创建复杂的数组,但是...我不知道该怎么做。
感谢您的帮助!
这是我的代码:

  #include< iostream> 
#include< fstream>
#include< complex>
#include< cmath>
使用命名空间std;

int const BrGr = 15,BrCv = BrGr + 1,BrSat = 24;
//(BrCv =节点数,BrSat =小时数)

int main()
{
//每个数组必须是动态数组。是一项任务。这是正确的方法吗?

auto * Ipot = new double [BrCv-1] [BrSat];
auto * cosfi = new double [BrCv-1] [BrSat];
自动* S_pot =新的复合物double [BrCv-1] [BrSat];
auto * I_inj =新的复合物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 ++)
{
阅读器>> Ipot [i] [j];
}
}
for(int i = 0; i< BrCv-1; i ++)
{
for(int j = 0; j< BrSat ; j ++)
{
reader>> cosfi [i] [j];
}
}
}
else cout<< 错误! <<恩德尔
reader.close();

//在这里我要创建2D复数数组-这是正确的方法吗?
//同样,在相同的过程中,我想计算每个节点每小时的S_pot值

for(int i = 0; i< BrCv-1; i ++)
{
for(int j = 0; j< BrSat; j ++)
{
S_pot [i] [j] = complex (Ipot [i] [j] * cosfi [i] [j],Ipot [i] [j] * sqr(1-pow(cosfi [i] [j],2)));
}
}
//这里,我给出节点每小时V_cvo的值

for(int i = 0; i< BrCv; i ++ )
{
for(int j = 0; j< BrSat; j ++)
{
V_cvo [i] [j] = 1;
}
}

//在这里,我想计算每个节点每小时

的I_inj的值(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]);
}
}

//这里我要删除所有数组

delete [] Ipot,cosfi,S_pot,I_inj,V_cvo;
system( pause);
返回0;


解决方案

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



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



在C ++中创建2D动态大小的数组是一个多阶段操作。

  double twoDArray [nrRows] [nrColumns]; 

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

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



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



这里是设置:

  double * arr [ ] =新的double * [nrRows]; //创建指向行
的行,用于(size_t index = 0; index< nrRows; index ++)
{
arr [index] = new double [nrColumns]; //创建列
}

这是清理工作

  for(size_t index = 0; index< nrRows; index ++)
{
delete [] arr [index]; //删除所有列
}
delete [] arr; //删除行

为了您的努力,您会变得很生气空间局部性和性能受到影响(造成高速缓存未命中)的原因是,您的许多阵列可能位于RAM中的任何位置,并且您会遇到糟糕的内存管理问题。搞砸了,一个意外的异常,则有内存泄漏。



下一个选项具有更好的局部性,因为有一个大数据数组可供读取,而不是从中读取,

  double * arr2 [] = new double * [nrRows]; //创建行以指向列
doubleholder [] = new double [nrRows * nrColumns]; //一次创建所有列
,用于(size_t index = 0; index< nrRows; index ++)
{
arr [index] =& holder [index * nrColumns]; //将列附加到行
}

并清理:

  delete [] arr2; 
delete []个持有人;

在C ++中,理智的人会在动态大小的数组上选择std :: vector,除非给出非常高的值, 非常 令人信服的理由。为什么在SO和整个Internet上都记录了死亡原因,而证据则是通过劫持的计算机为垃圾邮件和其他恶作剧堆积了垃圾。

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

使用情况恰好是用户习惯使用的数组:

  vec [i] [j] = somevalue; 

这实际上没有内存问题,但由于向量可能位于任何地方,因此又回到了cr脚的地方。 / p>

但是...!



还有更好的方法:使用一维数组并将其包装

  template< class TYPE> 
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)
{

}
类型& operator()(size_t行,size_t列)
{
return vec [row * mNrColumns + column];
}
TYPE运算符()(size_t行,size_t列)const
{
return vec [row * mNrColumns + column];
}
};

这个小动物将完成您需要2D向量执行的大部分操作。您可以复制它,也可以移动它。您可以收拾所有想要的东西。杰伊·莱诺(Jay Leno)会赚更多。



我直接跳到模板化版本是因为我很沮丧地两次解释了TwoDee类。



构造函数很简单。您给它提供数组的尺寸,并建立一个不错的,安全的一维向量。



operator()函数获取行索引和列索引,执行一些简单的算法即可将索引转换为a单个索引,然后返回对索引值的引用以允许进行修改,或者返回常量大小写的索引值副本。



如果您感觉需要

  TYPE&运算符()(size_t行,size_t列)
{
if(row< mNrRows&&列< mNrColumns)
{
return vec [row * mNrColumns +柱];
}
throw std :: out_of_range( Bad index);
}

确定。 OP如何使用它?

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

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

 为(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));
}
}


I am new in C++ programing so I need a help about 2D arrays. Is it possible to create complex array from two real array with two for loops?I was trying to do that in my code but...I do not know how to do that. Thanks for help! This is my code::

#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;

解决方案

Note: I'm using double through out these examples, but you can replace double with any type.

To be honest, you probably don't want to use a 2D array.

Creating a 2D dynamically-sized array in C++ is a multi-stage operation. You can't just

double twoDArray [nrRows][nrColumns];

or

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

There are a couple things wrong with this, but the most important is the rows and columns are not a constant, defined at compile time values. Some compilers allow the first, but this cannot be guaranteed. I don't know if any compiler allows the second.

Instead, First you create an array of rows to hold the columns, then you separately create each row of columns. Yuck.

Here's the set up:

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
}

And here's clean-up

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

For your efforts you get crappy spacial locality and the performance hit (Cache miss) that causes because your many arrays could be anywhere in RAM, and you get crappy memory management issues. One screw-up, one unexpected exception and you have a memory leak.

This next option has better locality because there is one big data array to read from instead of many, but still the same leakage problems.

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
}

and clean up:

delete[] arr2;
delete[] holder;

In C++, the sane person chooses std::vector over a dynamically-sized array unless given very, very compelling reason not to. Why has been documented to death all over SO and the Internet at large, and the proof litters the Internet with hijacked computers serving up heaping dollops of spam and other nastiness.

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

Usage is exactly what array users are used to:

vec[i][j] = somevalue;

This has effectively no memory problems, but is back to crappy locality because the vectors could be anywhere.

But...!

There is a better method still: Use a One Dimensional array and wrap it in a simple class to make it look 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];
    }
};

This little beastie will do most of what you need a 2D vector to do. You can copy it, you can move it. You can crunch all you want. Jay Leno will make more.

I jumped directly to the templated version because I'm stumped for a good reason to explain class TwoDee twice.

The constructor is simple. You give it the dimensions of the array and it builds a nice, safe 1D vector. No muss, no fuss, and No Zayn required.

The operator() functions take the row and column indices, do a simple bit of arithmetic to turn the indices into a single index and then either return a reference to the indexed value to allow modification or a copy of the indexed value for the constant case.

If you're feeling like you need extra safety, add in range checking.

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. How does the OP use this?

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

Created and ready to go. And to load it up:

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));
    }
}

这篇关于C ++中的2D复杂数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆