简体   繁体   English

在C ++中使用结构作为数据类型初始化向量的向量

[英]Initialise vector of vectors using structure as datatype in c++

I would rather use a class, but my requirement is simpler than that. 我宁愿使用一个类,但我的要求比这简单。 Which is to create a two dimensional array of elements, with each element representing a structure datatype. 这将创建元素的二维数组,每个元素代表一个结构数据类型。 The problem is when I try to do a variable initialisation after the multi vector is passed into a function. 问题是当我尝试将多向量传递给函数后进行变量初始化时。 The simple version of my code is as follows: 我的代码的简单版本如下:

#include <iostream>
#include <vector>

using namespace std;

struct Twalker
{
    int state;  
    float x,y; 
};`

void initialise(vector<vector<Twalker>>& walker,int n)
{   
   vector<Twalker> tempWalker;
   for (int i=0; i<n; i++)
   {
     tempWalker.state.push_back(+1); //need help!
     tempWalker.y.push_back(float(rand() % 10)); //need help!
     tempWalker.x.push_back(0.0); //need help!
   }
   walker.push_back(tempWalker);

}

int main(int argc, char** argv) 
{   
   int n = 5;
   vector<vector<Twalker>> walker;
   initialise(walker,n);
}

I have seen that we can add multiple values into a structure using push_back . 我已经看到可以使用push_back将多个值添加到结构中。 But i was trying to input values more liberally. 但是我试图更自由地输入价值。 Did I miss any syntax while using push_back ? 使用push_back是否错过任何语法? I started learning the concept of vectors few hours before and I am trying to shift my code from arrays into vectors . 数小时前,我开始学习向量的概念,并且尝试将代码从arrays转换为vectors

First of all, structures are equivalent to classes - the only difference is that their members are by default public, while class members are by default private. 首先,结构等效于类-唯一的区别是它们的成员默认情况下是公共的,而类成员默认是私有的。

Your program has multiple issues, and here is one possible solution to it: 您的程序有多个问题,这是它的一种可能的解决方案:

#include <iostream>
#include <vector>
#include <ctime>

using std::cin;
using std::cout;
using std::endl;
using std::vector;

struct Twalker
{
    int state;
    float x,y;
};

// Initialize the vector of vectors of Twalker objects
void initialise(vector<vector<Twalker>>& walker, int nv, int n)
{ 
    Twalker wlk;
    vector<Twalker> tempWalker;

    // Outer loop - vector of vectors
    for (int i=0; i<nv; i++){
        // Inner loop - vector of Twalker objects
        for (int j=0; j<n; j++){
            // Temporary Twalker
            wlk.state = 1;
            wlk.x = 0.0; 
            wlk.y = float(rand()%10);
            // Add it to the inner vector
            tempWalker.push_back(wlk);
        }
        // Add the inner vector to the vector of vectors
        walker.push_back(tempWalker);
        // Reset the inner vector
        tempWalker.clear();
    }
}

int main()
{
    // Set the seed
    std::srand(std::time(0));

    int nv = 3, n = 2;
    vector<vector<Twalker>> walker;

    // Initialize   
    initialise(walker, nv, n);

    // Print 
    for (int i = 0; i < nv; i++)
        for (int j = 0; j < n; j++)
            cout << walker[i][j].state << " " 
                 << walker[i][j].x << " "
                 << walker[i][j].y << endl; 
    return 0;
}

You should definitely read more on vectors including basics and concepts like iterators and size_t . 您绝对应该阅读有关向量的更多信息,包括基础知识和概念,例如迭代器和size_t Here I only used variations of what it seems you are familiar with, but some parts of this program would normally look quite different (like printing part). 在这里,我仅使用了您似乎熟悉的变体,但是该程序的某些部分通常看上去会完全不同(例如打印部分)。

Some notes and suggestions related to this code: 与该代码有关的一些注释和建议:

  • Generally don't use using namespace std . 通常不要using namespace std You may, for instance, end up overwriting stl functions with your own by accident. 例如,您可能会意外地最终用自己的功能覆盖stl函数。 It is more recommended to use using for specific, commonly used components like cin , cout , vector etc. 推荐它更使用using特定的,通常使用的类似的组件cincoutvector
  • You are initializing a vector of vectors - thus you need two loops in your initialization function (and possibly an extra parameter to control the vector of vectors size). 您正在初始化向量的向量-因此您在初始化函数中需要两个循环(可能还需要一个额外的参数来控制向量的大小)。
  • While you can access object (here Twalker) members directly from the vector, like in the print part at the end, you reversed the order for that in your program. 尽管可以直接从向量访问对象(这里是Twalker)成员,就像最后的打印部分一样,但是您可以在程序中颠倒顺序。 You would need to push back a temporary Twalker first and then fill each member with a value. 您将需要先推回临时Twalker,然后为每个成员填充一个值。 Here the Twalker is filled first and then pushed back. 在这里先行者被装满,然后被推回去。
  • At the end of the inner loop the inner (temporary) vector is cleared - its size is reset to 0. If not for this, the inner loop would be increasing the size of the vector each time it performs a push_back. 在内部循环的最后,清除内部(临时)向量-将其大小重置为0。否则,内部循环将在每次执行push_back时增加向量的大小。 Last vector in the vector of vectors would be nv times longer than the first! 向量中的最后一个向量比第一个向量长nv倍!
  • The srand function resets the random seed every time the program is ran. 每次运行程序时, srand函数都会重置随机种子。 Without it, executing the same program would always lead to the same set of random numbers. 没有它,执行相同的程序将始终导致相同的随机数集。
  • I normally use argc and argv only when I have command line arguments in the program. 我通常仅在程序中有命令行参数时才使用argcargv Also, you can but don't have to add a return 0 statement at the end of your main (compiler will add it for you if you don't). 另外,您可以但不必在主程序末尾添加return 0语句(如果不这样做,编译器会为您添加该语句)。
  • As @Caleth said in the comment, instead of clearing tempWalker after the inner loop, you can also declare it in the inner loop which will create a new, empty tempWalker vector each time the inner loop is re-entered. 就像@Caleth在评论中说的那样, tempWalker在内部循环之后清除tempWalker ,您还可以在内部循环中声明它,这将在每次重新进入内部循环时创建一个新的空tempWalker向量。 On the other hand, as noted by @MatteoItalia, this approach allocates and deallocates memory for the inner vector each time the inner loop is executed. 另一方面,如@MatteoItalia所指出,此方法每次执行内部循环时都会为内部向量分配和取消分配内存。 In larger programs with larger vectors this kind of redundant allocations will cause performance losses and should be avoided. 在带有较大向量的较大程序中,这种冗余分配会导致性能损失,应避免使用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM