Vector 中的 C++ 分组重复
C++ Grouping repetitions within Vector
我有一个结构如下的文件:
A 123456 0
G 123456 5
A 235334 0
B 123456 2
每条信息都是这样存储的:
temp.code >> temp.personid >> temp.data
我已将此信息存储在 Vector 中
ifstream fin("test.txt");
vector<TestClass> test;
TestClass temp;
string line;
while (getline(fin, line)) {//.. test.push_back(temp);}
给定的 personid 可以在文件中多次出现。
我想要做的是遍历向量并将重复分组到每个 personid 的单个 class 对象中,我的目标是我想对每个特定对象的数据求和,例如上面文件的输出将是:
123456 : 7
235334 : 0
处理这个问题的优雅方法是什么?
谢谢
使用Unordered map。在平均情况下,无序映射中的查找时间是常数 O(1)
。我使用矢量作为示例数据,您可以从文件而不是矢量加载数据。
#include <bits/stdc++.h>
using namespace std;
int main() {
unordered_map<string, int>m;
unordered_map<string, int>::iterator itr; // Iterator to iterate unordered map
vector<pair<string, int> >person_details; // pair of vector to represent sample data, you can load data from file instead
person_details.push_back(make_pair("123456",0));
person_details.push_back(make_pair("123456",5));
person_details.push_back(make_pair("235334",0));
person_details.push_back(make_pair("123456",2));
for(int i=0;i<person_details.size();i++)
{
if(m.find(person_details[i].first) == m.end() ) // If personId is not present in map, insert it
m[person_details[i].first]=person_details[i].second;
else m[person_details[i].first]+=person_details[i].second; // If personId is present in map, increment it.
}
for(itr=m.begin();itr!=m.end();itr++)
cout<<itr->first<<" "<<itr->second<<endl; // Displaying personId with occurance
return 0;
}
Output:
235334 0
123456 7
注意:您可以使用Map来获得常数O(LogN)
时间,其中N是大小容器数量。
下面的代码使用了评论中建议的 std::unordered_map
。它将逐行读取您的文件。
代码假定人的id是int
类型,代码是std::string
类型,数据是int
.
类型
它将每个 Person
(这里作为示例结构)插入到映射中。如果一个人的 id 已经存在,它将总结数据。这意味着此解决方案不使用临时 std::vector
,而仅使用 std::unordered_map
.
See live example with your data on ideone.com.
代码:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <unordered_map>
struct Person
{
std::string code;
int data;
};
typedef std::unordered_map<int, Person> PersonMap;
int main()
{
std::ifstream fin("test.txt");
PersonMap persons;
/* line by line reading */
for (std::string line; std::getline(fin, line); )
{
std::istringstream iss(line);
int personId;
Person personData;
/* parse line as std::string, int, int */
iss >> personData.code >> personId >> personData.data;
/* insert into map and save result */
std::pair<PersonMap::iterator, bool> insertResult =
persons.insert(std::pair<int, Person>(personId, personData));
/* if personId is already there */
if (!insertResult.second)
{
insertResult.first->second.data += personData.data;
}
}
/* output whole map */
for(auto const &person : persons)
{
std::cout << person.first << " : " << person.second.data << "\n";
}
std::cout << std::flush;
}
输出:
235334 : 0
123456 : 7
我有一个结构如下的文件:
A 123456 0
G 123456 5
A 235334 0
B 123456 2
每条信息都是这样存储的:
temp.code >> temp.personid >> temp.data
我已将此信息存储在 Vector 中
ifstream fin("test.txt");
vector<TestClass> test;
TestClass temp;
string line;
while (getline(fin, line)) {//.. test.push_back(temp);}
给定的 personid 可以在文件中多次出现。 我想要做的是遍历向量并将重复分组到每个 personid 的单个 class 对象中,我的目标是我想对每个特定对象的数据求和,例如上面文件的输出将是:
123456 : 7
235334 : 0
处理这个问题的优雅方法是什么?
谢谢
使用Unordered map。在平均情况下,无序映射中的查找时间是常数 O(1)
。我使用矢量作为示例数据,您可以从文件而不是矢量加载数据。
#include <bits/stdc++.h>
using namespace std;
int main() {
unordered_map<string, int>m;
unordered_map<string, int>::iterator itr; // Iterator to iterate unordered map
vector<pair<string, int> >person_details; // pair of vector to represent sample data, you can load data from file instead
person_details.push_back(make_pair("123456",0));
person_details.push_back(make_pair("123456",5));
person_details.push_back(make_pair("235334",0));
person_details.push_back(make_pair("123456",2));
for(int i=0;i<person_details.size();i++)
{
if(m.find(person_details[i].first) == m.end() ) // If personId is not present in map, insert it
m[person_details[i].first]=person_details[i].second;
else m[person_details[i].first]+=person_details[i].second; // If personId is present in map, increment it.
}
for(itr=m.begin();itr!=m.end();itr++)
cout<<itr->first<<" "<<itr->second<<endl; // Displaying personId with occurance
return 0;
}
Output:
235334 0
123456 7
注意:您可以使用Map来获得常数O(LogN)
时间,其中N是大小容器数量。
下面的代码使用了评论中建议的 std::unordered_map
。它将逐行读取您的文件。
代码假定人的id是int
类型,代码是std::string
类型,数据是int
.
它将每个 Person
(这里作为示例结构)插入到映射中。如果一个人的 id 已经存在,它将总结数据。这意味着此解决方案不使用临时 std::vector
,而仅使用 std::unordered_map
.
See live example with your data on ideone.com.
代码:
#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <unordered_map>
struct Person
{
std::string code;
int data;
};
typedef std::unordered_map<int, Person> PersonMap;
int main()
{
std::ifstream fin("test.txt");
PersonMap persons;
/* line by line reading */
for (std::string line; std::getline(fin, line); )
{
std::istringstream iss(line);
int personId;
Person personData;
/* parse line as std::string, int, int */
iss >> personData.code >> personId >> personData.data;
/* insert into map and save result */
std::pair<PersonMap::iterator, bool> insertResult =
persons.insert(std::pair<int, Person>(personId, personData));
/* if personId is already there */
if (!insertResult.second)
{
insertResult.first->second.data += personData.data;
}
}
/* output whole map */
for(auto const &person : persons)
{
std::cout << person.first << " : " << person.second.data << "\n";
}
std::cout << std::flush;
}
输出:
235334 : 0 123456 : 7