C++ 将唯一数据推入向量
我有以下数据:C++ 将唯一数据推入向量,c++,insert,unique,stdvector,C++,Insert,Unique,Stdvector,我有以下数据: FolioA Name1 100 FolioA Name2 110 FolioA Name3 100 FolioB Name1 100 FolioB Name3 106 FolioC Name1 108 FolioC Name2 102 FolioC Name3 110 我只想在中插入唯一的名称(即名称1、名称2和名称3各一次) std::向量名; 当我遍历数据时 因此,我有以下代码,其中我将数据存储在一个名为test的映射中: std::map<std::string
FolioA Name1 100
FolioA Name2 110
FolioA Name3 100
FolioB Name1 100
FolioB Name3 106
FolioC Name1 108
FolioC Name2 102
FolioC Name3 110
我只想在中插入唯一的名称(即名称1、名称2和名称3各一次)
std::向量名;
当我遍历数据时
因此,我有以下代码,其中我将数据存储在一个名为test的映射中:
std::map<std::string, std::map<std::string, double> >test;
std::map<std::string, std::map<std::string, double > >::iterator it1 = test.begin(), end1 = test.end();
while (it1 !=end1) {
std::map<std::string, double>::iterator it2 = it1->second.begin(), end2=it1->second.end();
**name.push_back(it2->first);**
++it2;
}
++it1;
}
std::maptest;
std::map::迭代器it1=test.begin(),end1=test.end();
while(it1!=end1){
迭代器it2=it1->second.begin(),end2=it1->second.end();
**name.push_back(it2->first)**
++it2;
}
++it1;
}
但是,目前,通过按我的方式将数据推入name,有3个Name1实例、2个Name2实例和3个Name3实例,这是我的代码所期望的。如何将其修复为只有唯一的名称。如果您不关心要将哪个实例输入到数据结构中,这将符合您的目的由于要保留给定名称的第一个实例,您必须在某个点执行名称查找。一个只涉及向量的简单算法是使用 然后,以@Chad为例
std::vector<std::string> name(names_set.begin(), name_set.end());
std::vector name(name_set.begin(),name_set.end());
如果您没有C++11,哈希映射的替代方法是
boost::hash_-map
和tr1::hash_-map
也许您应该使用向量的另一个映射头来拥有唯一的名称
std::map
std::set<std::string> unique_names;
// ...
while (it1 !=end1)
{
// ...
// **name.push_back(it2->first);**
unique_names.insert(it2->first);
}
std::vector<std::string> name(unique_names.begin(), unique_names.end());
std::设置唯一的\u名称;
// ...
while(it1!=end1)
{
// ...
//**名称。推回(it2->first)**
唯一的名称。插入(it2->first);
}
std::vector name(unique_names.begin(),unique_names.end());
列表具有.sort()和.unique()的功能,这将为您提供
您可以使用迭代器对其进行迭代,并使用初始值设定项\u list对其进行初始化
在我看来,这些数据实际上更像一个结构:
#include <iterator>
#include <list>
#include <string>
#include <fstream>
typedef struct NODE_S {
string name1, name2;
int n;
} NODE_S NODE;
bool compare_NODE (NODE first, NODE second)
{
unsigned int i=0;
if (first.name1 < second.name1) {
return true;
} else if (first.name2 < second.name2) {
return true;
} else if (first.n < second.n) {
return true;
} else { return false;}
}
bool readfile(list<NODE>& ln, string filepath) {
std::ifstream filein;
NODE n;
filein.open(filepath.c_str(), std::iofstream::in);
if (!filein.good()) {
filein.close();
std::cerr << "ERROR: unable to open file \"" << filepath << "\" or file is zero-length." << std::endl;
return false;
}
do {
filein >> n.name1 >> n.name2 >> n.name3 >> std::skipws;
ln.push_back(n);
ln.sort(compare_NODE);
ln.unique();
//add node to list
} while (!filein.good()); //can use .eof here, but if bad disk blocks...
filein.close();
return true;
}
int main(int argc, char * argv[], char * envp[]) {
string filepath="somefile.txt";
if (!readfile(filepath)) {
return 1;
}
list<NODE>::iterator lni;
for (lni = ln.begin(); lni != ln.end(); lni++) {
std::cout<<lni->name1<<' '<<lni->name2<<' '<<lni->n<<std::endl;
}
return 0;
}
#包括
#包括
#包括
#包括
类型定义结构节点{
字符串名称1,名称2;
int n;
}节点的节点;
布尔比较_节点(节点第一,节点第二)
{
无符号整数i=0;
if(first.name1>n.name2>>n.name3>>标准:skipws;
ln.推回(n);
项次排序(比较节点);
ln.unique();
//将节点添加到列表中
}虽然(!filein.good());//可以在这里使用.eof,但是如果坏磁盘阻塞。。。
filein.close();
返回true;
}
int main(int argc,char*argv[],char*envp[]{
字符串filepath=“somefile.txt”;
如果(!readfile(filepath)){
返回1;
}
列表::迭代器lni;
对于(lni=ln.begin();lni!=ln.end();lni++){
std::coutHow你会选择包含哪个实例?你必须有一个向量
的名称吗?我建议使用一个集
的名称来代替。如果你必须有一个向量,你仍然可以先插入到一个集中,然后使用构造函数重载将对象移动到向量
,这个重载需要迭代或者
s.@juanchopanza,我会选择每个的第一个实例,因此如果向量已经包含(Name1,Name2,Name3),然后当它点击第四条记录时,它识别出该记录已经存在,因此跳过它,并转到下一条记录。@Chad,你能发布示例代码吗?啊哈,听起来它可能会这样做。你能发布示例代码说明我将如何使用它吗..即O(N*N)
。这是可行的,但Chad的解决方案的可扩展性要好得多。@mAlters,也许你可以解释为什么你会这样分类。Chad的解决方案也可行,但上面的错误是什么。@user1155299问题是这个算法不是很有效,即它的复杂度是不必要的高。我提供了一个更好的例子w有一些解释。@MSalters非常正确。Chad的解决方案没有解决实际问题,但非常接近。我已经用一些解释更新了我的答案。你需要将排序
和唯一
调用移到循环外。现在,它们在每个节点
调用一次。顺便说一句,类型定义结构
的东西20年来都不需要了。
std::vector<std::string> name(names_set.begin(), name_set.end());
std::set<std::string> unique_names;
// ...
while (it1 !=end1)
{
// ...
// **name.push_back(it2->first);**
unique_names.insert(it2->first);
}
std::vector<std::string> name(unique_names.begin(), unique_names.end());
#include <iterator>
#include <list>
#include <string>
#include <fstream>
typedef struct NODE_S {
string name1, name2;
int n;
} NODE_S NODE;
bool compare_NODE (NODE first, NODE second)
{
unsigned int i=0;
if (first.name1 < second.name1) {
return true;
} else if (first.name2 < second.name2) {
return true;
} else if (first.n < second.n) {
return true;
} else { return false;}
}
bool readfile(list<NODE>& ln, string filepath) {
std::ifstream filein;
NODE n;
filein.open(filepath.c_str(), std::iofstream::in);
if (!filein.good()) {
filein.close();
std::cerr << "ERROR: unable to open file \"" << filepath << "\" or file is zero-length." << std::endl;
return false;
}
do {
filein >> n.name1 >> n.name2 >> n.name3 >> std::skipws;
ln.push_back(n);
ln.sort(compare_NODE);
ln.unique();
//add node to list
} while (!filein.good()); //can use .eof here, but if bad disk blocks...
filein.close();
return true;
}
int main(int argc, char * argv[], char * envp[]) {
string filepath="somefile.txt";
if (!readfile(filepath)) {
return 1;
}
list<NODE>::iterator lni;
for (lni = ln.begin(); lni != ln.end(); lni++) {
std::cout<<lni->name1<<' '<<lni->name2<<' '<<lni->n<<std::endl;
}
return 0;
}