【问题标题】:How to insert variable amount of data in 2d array in c++如何在c ++中的二维数组中插入可变数量的数据
【发布时间】:2018-10-17 14:32:09
【问题描述】:

我有以下包含值的文件 input.txt:

0 0
0 1
0 2
0 3
1 1
1 4
2 1
2 4
2 3

我想将这些值插入两个数组。我希望他们最终看起来像这样。

0   0 1 2 3
1   1 4
2   1 4 3

第一个数组将包含 id,第二个数组将包含元素。我已经设法使用以下方法为这两个数组动态分配内存:

int n,m,i=0,tempNum,lines;
int NumberOfIds=0;
ifstream read("input2.txt");
while(read>>n>>m){
    if (i==0){
        tempNum=n;
    }
    if (tempNum != n){
        NumberOfIds++;
    }
    tempNum = n;
    i++;
}
lines=i-1;

//printf("%d", j);
int** idElements = new int*[NumberOfIds];
int* ids = new int[NumberOfIds];
int* numberOfIdElements = new int[NumberOfIds];

// Rewinds file
read.clear();
read.seekg(0, ios::beg);

int counter = 0;
NumberOfIds=0;
while(read>>n>>m){

    if (tempNum != n){
        numberOfIdElements[NumberOfIds] = counter;
        NumberOfIds++;
        counter = 0;
    }
    tempNum = n;
    counter++;
    i++;
}

for(int k = 0; k < NumberOfIds; ++k)
    idElements[k] = new int[numberOfIdElements[k]];

现在我被困在如何插入数据上。任何帮助将不胜感激。

【问题讨论】:

    标签: c++ arrays file input dynamic-memory-allocation


    【解决方案1】:

    你可以用std::vector's相当容易地做到这一点:

    std::vector<std::vector<int>> arr;
    while(read>>n>>m){
        //if we're too small, push empty rows till we're big enough
        while(n + 1 > arr.size()) {
            arr.push_back(std::vector<int>());
        }
        arr.at(n).push_back(m); //push m onto row n
    }
    

    或者,如果您的第一列编号变大(因此您不想创建很多空行),您可以使用std::map

    std::map<int, std::vector<int>> arr;
    while(read>>n>>m){
        //works because map subscript creates a key/val pair if one doesn't exist
        //so if this row doesn't exist, we get a new vector to push_back to
        arr[n].push_back(m); //push m onto row n
    }
    

    在此处查看实际操作:ideone

    【讨论】:

    • 感谢您的回答。我是 C++ 新手。你能指导我如何打印矢量的内容吗?
    • 您可以像遍历数组一样遍历std::vectorfor(int x = 0; x &lt; arr.size(); x++) { cout &lt;&lt; arr[x] ... },或者由于它是一个 STL 容器,您可以使用带有迭代器 for(auto x : arr) { ... 的更高级的方法。有关更多信息,请参阅here
    • @scohe001 afaik 基于迭代器的循环和基于范围的新循环都不需要 stl 容器,它们都应该与 c 数组一起使用
    • @user463035818 我想我只是不需要使用 c 样式的数组,因为我已经开始使用基于范围的循环......谢谢你的收获!
    • @thelaw 向量实现的方式是查看我们当前创建了多少行,然后查看下一个数字将属于哪一行。如果下一行大于我们分配了多少,它将继续分配,直到我们有那么多行。如果您只有行 1, 100, 10000 的值,这可能是个问题。在这种情况下,您最终会创建 10000 向量,而 9998 将毫无用处,而 map 实现只会创建 3 个。
    【解决方案2】:

    这是使用集合映射的另一种方法:

    #include <sstream>
    #include <string>
    #include <iostream>
    #include <fstream>
    #include <map>
    #include <set>
    
    int main()
    {
        std::map<int, std::set<int>> m;
        std::ifstream ifs{"input.txt"};
    
        // read 
        for(std::string line; std::getline(ifs, line);){
            std::stringstream ss{line};
            int key;
            ss >> key;
            for (int val; ss >> val;)
                m[key].insert(val);
        }
    
        // print
        for(auto i : m) {
            std::cout << i.first << '\t';
            for(auto j : i.second)
                std::cout << j << ' ';
            std::cout << '\n';
        }
    }
    

    您可以根据您对排序或保留重复项的要求选择其他容器。

    【讨论】:

      猜你喜欢
      • 2021-09-10
      • 1970-01-01
      • 2020-11-08
      • 2019-08-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多