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

时间:2018-03-14 23:44:05

标签: c++ c++11 struct

我宁愿使用一个类,但我的要求比这简单。这是创建二维元素数组,每个元素表示一个结构数据类型。问题是当我将多个向量传递给函数后尝试进行变量初始化时。我的代码的简单版本如下:

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

我已经看到我们可以使用push_back将多个值添加到结构中。但我试图更自由地输入价值观。使用push_back时是否遗漏了任何语法?几个小时前我开始学习向量的概念,我试图将代码从arrays转移到vectors

1 个答案:

答案 0 :(得分:1)

首先,结构等同于类 - 唯一的区别是它们的成员默认是公共的,而类成员默认是私有的。

您的程序有多个问题,以下是一个可能的解决方案:

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

你绝对应该阅读更多关于向量的内容,包括迭代器和size_t等基础知识和概念。在这里我只使用了你熟悉的变体,但是这个程序的某些部分通常看起来很不一样(比如打印部分)。

与此代码相关的一些注意事项和建议:

  • 一般不要使用using namespace std。例如,您可能会意外地用自己的方法覆盖stl函数。建议您将using用于特定的常用组件,例如cincoutvector等。
  • 您正在初始化向量向量 - 因此您需要在初始化函数中使用两个循环(并且可能需要一个额外的参数来控制向量大小的向量)。
  • 虽然您可以直接从向量访问对象(此处为Twalker)成员,但最后是打印部分,您可以在程序中颠倒该顺序。您需要首先推回临时Twalker,然后使用值填充每个成员。在这里,Twalker首先被填充,然后被推回。
  • 在内部循环结束时,内部(临时)向量被清除 - 其大小被重置为0.如果不是这样,内部循环将在每次执行push_back时增加向量的大小。向量向量中的最后一个向量比第一个长nv倍!
  • srand函数每次运行程序时都会重置随机种子。没有它,执行相同的程序将始终导致相同的随机数集。
  • 我通常只在程序中有命令行参数时使用argcargv。此外,您可以但不必在main的末尾添加return 0语句(如果您不这样做,编译器将为您添加它)。
  • 正如@Caleth在评论中所说,不是在内循环之后清除tempWalker,而是在内循环中声明它,每次内部循环都会创建一个新的空tempWalker向量循环重新进入。另一方面,正如@MatteoItalia所指出的,这种方法在每次执行内部循环时为内部向量分配和释放内存。在具有较大向量的较大程序中,这种冗余分配将导致性能损失,应该避免。