如何从文件中填充集合向量的向量?

Posted

技术标签:

【中文标题】如何从文件中填充集合向量的向量?【英文标题】:How to populate a vector of vector of set from file? 【发布时间】:2020-10-09 20:01:00 【问题描述】:

我的 txt 文件中有一个 3x3 矩阵,其中包含一些数字和一些像这样的零

0 0 3
1 0 0
0 2 0

我想把它读成一组向量的向量。在我有零的地方,我想用数字 123 填充那个单元格。喜欢

1231233
1123123
1232123

我想知道我是否打印正确。

我已经写了这段代码:

class Matrix 
  private:
    vector<vector<set<int> > > cell;
  public:
    Matrix(const string& filename)  
        ifstream file("matrix.txt");
        if (!file.good())   
                cerr<<"Error";
            

        int x;
        int y;
        for(x=0; x<3; x++)  
            for(y=0; y<3; y++)  
              for(vector<vector<set<int> > >::iterator it = cell.begin(); it != cell.end(); it++)   
                if(file != 0)   
                 cell[x][y] = file; // Don't think this part of code is good because I get error here
                   else    
                   int z;
                   for(z = 1; z<4; z++) 
                     cell[x][y].insert(z);
                     cout<<cell[x][y];  // Of course I get an error here too.       
                        
                    
                
            
        
    

这个迭代有什么用吗?我没有在任何地方使用“它”,但我认为我必须使用它。

当然有些东西不正确或缺失,但我不明白是什么以及为什么。 我必须使用向量和集合。

我宁愿打印出来看看我做得好不好。

编辑 尝试写入文件>> cell[x][y]; 给我这个错误:[Error] cannot bind 'std::basic_istream' lvalue to 'std::basic_istream&&'。

【问题讨论】:

cell[x][y] = file; --> file &gt;&gt; cell[x][y];?请写一个minimal reproducible example,例如cell是什么? 你有一个二维矩阵 - vector&lt;vector&lt;int&gt;&gt; 将是一个合理的数据类型来存储它 - 你也不需要 set 原则很简单:避免为您不会使用的东西付费。如果您不需要动态重新分配数组(即矩阵),请使用静态分配的数组(如@VladFeinstein 建议的数组,或至少预先分配内存)。如果您要直接访问您的单元格项目(即通过索引访问它们),请不要使用类似 set 的树状结构。此外,如果您使用 set 您需要为单元格项目的排序付费,如果您想保持插入顺序,这甚至可能是不可取的。原理很简单,但你必须学习你的数据结构...... 我想到的另一件事:您可能希望将整个矩阵保存在一个连续的内存块中,以帮助您的 CPU 更快地访问内容,并且通过使用向量向量,您无法保证这就是即将发生的事情。因此,如果您知道矩阵/网格的大小和单元格上的项目数,请尝试分配一大块内存以将它们全部组合在一起(例如:int matrix[NumRows * NumCols * CellSize]); 如果您认为您会经常删除/添加单元格项目/元素,那么请考虑使用链表 (std::list)。如果您要更频繁地读取/访问您的单元格项目/元素然后删除/添加它们,那么考虑使用特殊值(例如,std::numeric_limits::min(),如果你能负担得起失去 1 个值,ofc) 表示已删除的项目/元素(即,值 -2147483648 表示该元素已被删除)。 【参考方案1】:

你已经声明了你的向量向量,但是它们都是空的;您无法通过索引访问任何元素。您可能希望将它们的大小分别调整为 3 元素。

如果你知道他们是3x3,就用std::array

std::array< std::array<std::set<int>, 3>, 3> cell;

另外,set 没有实现运算符 &lt;&lt;,所以你必须自己做(带循环):

cell[1][2].insert(7);
cell[1][2].insert(13);
for(auto x: cell[1][2])
  std::cout << x;
std::cout << std::endl;

同样适用于操作员&gt;&gt;:

int val(0);
std::cin >> val;
cell[1][2].insert(val);

附: Matrix 的构造函数中发生了太多事情。如果文件"matrix.txt" 不存在怎么办?还是格式错误?你会有一个无效的对象,所以要使用它,你需要实现类似valid() 方法的东西。最好构造一个空矩阵并以不同的方法加载它,例如load()

以下是如何使用矢量、加载和打印:

std::vector<std::vector<std::set<int>>> cell(3, std::vector<std::set<int>>(3));
// load from file
int val(0);
for (int x = 0; x < 3; x++) 
  for (int y = 0; y < 3; y++) 
    file >> val;
    cell[x][y].insert(val);
    


// print
for (int x = 0; x < 3; x++) 
  for (int y = 0; y < 3; y++) 
    for (auto it = cell[x][y].begin(); it != cell[x][y].end(); it++)
      std::cout << *it;
    

当然,这不会打印任何内容,因为集合是空的。你可以像我上面那样读入那些集合。

【讨论】:

如果我想使用向量怎么办?我可以用:vector&lt;set&lt;int&gt; &gt; row = vector&lt;set&lt;int&gt; &gt;(3); 然后vector&lt;vector&lt;set&lt;int&gt; &gt; &gt; cell = vector&lt;vector&lt;set&lt;int&gt; &gt; &gt;(3, row); 声明它应该可以吗?我可以像在代码中那样使用迭代器进行打印吗? (并使用std::cout)从文件中读取该矩阵怎么样? 我更新了,对不起,我没有写,因为我不想写太多无用的代码来问我的问题 我如何从存储这些集合中已经存在的数字的文件中读取该矩阵? 查看另一个更新。但是,我已经在我的回答开头向您展示了如何加载单个单元格。

以上是关于如何从文件中填充集合向量的向量?的主要内容,如果未能解决你的问题,请参考以下文章

从向量的向量填充向量的有效方法是啥?

如何使用算法填充向量的向量

从集合向量中移除集合

C++ OOP,输出对象指针向量时的空白控制台,不确定填充向量是不是正确

如何填充结构的向量

将文件读入类对象的向量