为什么不止一个元素没有插入一组结构中?
Why is more than one element not inserting in a set of structures?
我想将多个结构对象插入到一个集合中,但只有一个元素被插入到集合中。我做错了什么?
struct Productions {
char LHS;
string RHS;
bool operator<(const Productions& t) const {
return (this->LHS < t.LHS);
}
};
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
set<Productions> old_prod;
Productions prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
cout<<"LHS: ";
cin>>prod.LHS;
cout<<"RHS: ";
cin>>prod.RHS;
old_prod.insert(prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
输出是这样的:
terminal snippet.
我也试过:
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
set<Productions> old_prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
Productions *prod = new Productions;
cout<<"LHS: ";
cin>>prod->LHS;
cout<<"RHS: ";
cin>>prod->RHS;
old_prod.insert(*prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
但输出保持不变。我错过了什么?
如果您插入的元素具有相同的 LHS
,根据您的运算符<,它们被认为是等价的,并且一个集合只存储等价元素的一个实例。
来自 cppreference:
std::set
is an associative container that contains a sorted set of unique objects of type Key.
如果集合中已经存在等效元素,则通过简单地不插入元素来确保唯一性。请参阅 insert
:
上的文档
Inserts element(s) into the container, if the container doesn't already contain an element with an equivalent key.
如果 a<b
和 b<a
的计算结果都不为真,则 a
和 b
这两个元素被认为是等价的。注意,等价并不一定意味着相等,即a == b
。当您仅比较 operator<
中的 LHS
时,具有相同 LHS
的两个条目被认为是等效的(请参阅 here 以了解标准中的相关引用)。您可以让等价元素相等,但是您还需要在运算符中比较 RHS
。
不清楚你为什么选择一套,因为上面的属性基本上就是让一套成为一套的原因。也许您想改用 std::vector
。或者,您可以将您的操作员也修改为 comapre RHS
。
您正在为数据成员输入相同的值 char LHS;
。并且元素在集合中根据这个数据成员排序
bool operator<(const Productions& t) const {
return (this->LHS < t.LHS);
}
所以除了集合中的第一个输入外,所有其他输入都将被忽略。
对数据成员使用不同的值 LHS
。
或者按照下面的方式重新定义比较运算符
bool operator<(const Productions& t) const {
return this->LHS < t.LHS && this->RHS < t.RHS;
}
或者如果要使用元组则写
bool operator<(const Productions& t) const {
return std::tie( this->LHS, this->RHS ) < std::tie( t.LHS, t.RHS );
}
在这种情况下,您必须包括 header <tuple>
。
这是一个演示程序
#include <iostream>
#include <string>
#include <tuple>
#include <set>
using namespace std;
struct Productions {
char LHS;
string RHS;
bool operator<(const Productions& t) const {
return std::tie( this->LHS, this->RHS ) < std::tie( t.LHS, t.RHS );
}
};
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
set<Productions> old_prod;
Productions prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
cout<<"LHS: ";
cin>>prod.LHS;
cout<<"RHS: ";
cin>>prod.RHS;
old_prod.insert(prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
它的输出可能看起来像
Enter No. of Productions: 3
Enter Production No. 1:
LHS: S
RHS: aSa
Enter Production No. 2:
LHS: S
RHS: bSb
Enter Production No. 3:
LHS: S
RHS: c
3
S->aSa
S->bSb
S->c
另一种方法是使用 std::multiset
而不是 std::set
如果您想要键的重复值。
例如
#include <iostream>
#include <string>
#include <set>
using namespace std;
struct Productions {
char LHS;
string RHS;
bool operator<(const Productions& t) const {
return (this->LHS < t.LHS);
}
};
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
multiset<Productions> old_prod;
Productions prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
cout<<"LHS: ";
cin>>prod.LHS;
cout<<"RHS: ";
cin>>prod.RHS;
old_prod.insert(prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
我想将多个结构对象插入到一个集合中,但只有一个元素被插入到集合中。我做错了什么?
struct Productions {
char LHS;
string RHS;
bool operator<(const Productions& t) const {
return (this->LHS < t.LHS);
}
};
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
set<Productions> old_prod;
Productions prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
cout<<"LHS: ";
cin>>prod.LHS;
cout<<"RHS: ";
cin>>prod.RHS;
old_prod.insert(prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
输出是这样的: terminal snippet.
我也试过:
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
set<Productions> old_prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
Productions *prod = new Productions;
cout<<"LHS: ";
cin>>prod->LHS;
cout<<"RHS: ";
cin>>prod->RHS;
old_prod.insert(*prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
但输出保持不变。我错过了什么?
如果您插入的元素具有相同的 LHS
,根据您的运算符<,它们被认为是等价的,并且一个集合只存储等价元素的一个实例。
来自 cppreference:
std::set
is an associative container that contains a sorted set of unique objects of type Key.
如果集合中已经存在等效元素,则通过简单地不插入元素来确保唯一性。请参阅 insert
:
Inserts element(s) into the container, if the container doesn't already contain an element with an equivalent key.
如果 a<b
和 b<a
的计算结果都不为真,则 a
和 b
这两个元素被认为是等价的。注意,等价并不一定意味着相等,即a == b
。当您仅比较 operator<
中的 LHS
时,具有相同 LHS
的两个条目被认为是等效的(请参阅 here 以了解标准中的相关引用)。您可以让等价元素相等,但是您还需要在运算符中比较 RHS
。
不清楚你为什么选择一套,因为上面的属性基本上就是让一套成为一套的原因。也许您想改用 std::vector
。或者,您可以将您的操作员也修改为 comapre RHS
。
您正在为数据成员输入相同的值 char LHS;
。并且元素在集合中根据这个数据成员排序
bool operator<(const Productions& t) const {
return (this->LHS < t.LHS);
}
所以除了集合中的第一个输入外,所有其他输入都将被忽略。
对数据成员使用不同的值 LHS
。
或者按照下面的方式重新定义比较运算符
bool operator<(const Productions& t) const {
return this->LHS < t.LHS && this->RHS < t.RHS;
}
或者如果要使用元组则写
bool operator<(const Productions& t) const {
return std::tie( this->LHS, this->RHS ) < std::tie( t.LHS, t.RHS );
}
在这种情况下,您必须包括 header <tuple>
。
这是一个演示程序
#include <iostream>
#include <string>
#include <tuple>
#include <set>
using namespace std;
struct Productions {
char LHS;
string RHS;
bool operator<(const Productions& t) const {
return std::tie( this->LHS, this->RHS ) < std::tie( t.LHS, t.RHS );
}
};
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
set<Productions> old_prod;
Productions prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
cout<<"LHS: ";
cin>>prod.LHS;
cout<<"RHS: ";
cin>>prod.RHS;
old_prod.insert(prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}
它的输出可能看起来像
Enter No. of Productions: 3
Enter Production No. 1:
LHS: S
RHS: aSa
Enter Production No. 2:
LHS: S
RHS: bSb
Enter Production No. 3:
LHS: S
RHS: c
3
S->aSa
S->bSb
S->c
另一种方法是使用 std::multiset
而不是 std::set
如果您想要键的重复值。
例如
#include <iostream>
#include <string>
#include <set>
using namespace std;
struct Productions {
char LHS;
string RHS;
bool operator<(const Productions& t) const {
return (this->LHS < t.LHS);
}
};
int main() {
int NoP;
cout<<"Enter No. of Productions: ";
cin>>NoP;
multiset<Productions> old_prod;
Productions prod;
for(int i=0; i<NoP; i++) {
cout<<"Enter Production No. "<<i+1<<":"<<endl;
cout<<"LHS: ";
cin>>prod.LHS;
cout<<"RHS: ";
cin>>prod.RHS;
old_prod.insert(prod);
}
cout<<old_prod.size()<<endl;
for(auto it=old_prod.begin(); it!=old_prod.end(); it++) {
cout<<it->LHS<<"->"<<it->RHS<<endl;
}
}