I have the following file input.txt which contains the values :
我有以下文件input.txt,其中包含值:
0 0
0 1
0 2
0 3
1 1
1 4
2 1
2 4
2 3
I want to insert these values to two arrays. I want them to look like this in the end.
我想将这些值插入两个数组。我希望他们最终看起来像这样。
0 0 1 2 3
1 1 4
2 1 4 3
First array will contain the id and second array will contain the elements. I have managed to dynamically allocate memory for these two arrays using the following :
第一个数组将包含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]];
Now I am stuck in how to insert the data. Any help would be appreciated.
现在我陷入了如何插入数据的困境。任何帮助,将不胜感激。
2 个解决方案
#1
2
You can do this with std::vector
's fairly easily:
你可以很容易地使用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
}
Alternatively, if your first column numbers become large (so you wouldn't want to make many empty rows), you can use an std::map
:
或者,如果您的第一个列号变大(因此您不希望创建许多空行),则可以使用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
}
See it in action here: ideone
在这里看到它:ideone
#2
1
Here is another approach using a map of sets:
这是另一种使用集合映射的方法:
#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';
}
}
You might select other containers depending of your requirements for sorting or preserving duplicates.
您可以根据您的要求选择其他容器进行排序或保留重复项。
#1
2
You can do this with std::vector
's fairly easily:
你可以很容易地使用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
}
Alternatively, if your first column numbers become large (so you wouldn't want to make many empty rows), you can use an std::map
:
或者,如果您的第一个列号变大(因此您不希望创建许多空行),则可以使用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
}
See it in action here: ideone
在这里看到它:ideone
#2
1
Here is another approach using a map of sets:
这是另一种使用集合映射的方法:
#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';
}
}
You might select other containers depending of your requirements for sorting or preserving duplicates.
您可以根据您的要求选择其他容器进行排序或保留重复项。