Как вставить переменное количество данных в 2d массив в C ++ - PullRequest
0 голосов
/ 07 мая 2018

У меня есть следующий файл 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

Первый массив будет содержать идентификатор, а второй массив будет содержать элементы. Мне удалось динамически выделить память для этих двух массивов, используя следующее:

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

Теперь я застрял в том, как вставить данные. Любая помощь будет оценена.

Ответы [ 2 ]

0 голосов
/ 07 мая 2018

Вот еще один подход, использующий карту множеств:

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

Вы можете выбрать другие контейнеры в зависимости от ваших требований для сортировки или сохранения дубликатов.

0 голосов
/ 07 мая 2018

Вы можете сделать это с помощью std::vector довольно легко:

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

...