比较std::对的2个std::列表
Comparing 2 std::lists of std::pairs
我希望你能在这里帮我。我已经搜索了其他答案,但没有找到符合我具体情况的答案(但如果你找到了,请告诉我网址!)。我看到了很多关于使用std::map而不是list的建议,如果需要的话,我不介意切换容器。
目前,我有两个配对列表,即
std:list <std::pair<string,string>> outputList1;
std:list <std::pair<string,string>> outputList2;
我已经用从SQL数据库中检索到的用户设置填充了每个列表(这里省略了SQL检索代码)。
示例列表:
outputList1(第一个,第二个)
CanSeeAll,True
CanSubmit,False
CanControl,False
OutputList2:
CanSeeAll,False
CanSubmit,True
CanControl,False
我想遍历这两个列表,找出不匹配的地方。例如,找到第一个列表的第一对中的第一个字符串以找到第二个列表中匹配的第一个串,然后比较第二个字符串以确定它们是否匹配,然后将不匹配的对打印到新的字符串中(最终打印到文件中),依此类推
在本例中,最后一个字符串将CanSeeAll和CanSubmit作为最终输出,因为这两个字符串不匹配。
以下是我迄今为止尝试过的内容,但我得到了一个空白字符串:
std::list <std::pair<std::string,std::string>>::iterator it1 = outputList1.begin();
std::list <std::pair<std::string,std::string>>::iterator it2 = outputList2.begin();
string token;
while (it1 != outputList1.end()){
if((*it1).first == ((*it2).first))
{
if((*it1).second != ((*it2).second))
{
token.append((*it1).first);
token.append(",");
token.append((*it1).second);
token.append("rn");
}
it1++;
it2 = outputList2.begin();
}
it2++;
if (it2 == outputList2.end())
it1++;
}
我知道这个逻辑是有缺陷的,因为它会在第一次迭代后跳过第二个列表中的第一对,但这是我目前能想到的最好的,我现在正在敲击键盘。
谢谢大家!
根据我对问题的理解,
您希望将一个列表中的每个元素与另一个列表的其他元素进行比较
您可以使用一对基于嵌套范围的for循环。
#include <list>
#include <string>
int main(){
std::list<std::pair<std::string,std::string>> l1;
std::list<std::pair<std::string,std::string>> l2;
for (auto x: l1){
for (auto y: l2){
//compare x to y
}
}
}
答案使用辅助映射,但请记住,如果使用两个映射(或哈希表)而不是两个列表,则会得到更好的结果。
// create a map for elements in l2
std::map<std::string, std::string> l2map;
// move elements from l2 to the map so we get O(N*log(N)) instead of O(n²)
for (std::list<std::pair<std::string,std::string> >::iterator it = l2.begin();
it != l2.end();
++it)
{
l2map.insert(*it);
}
// walk l1 and look in l2map
for (std::list<std::pair<std::string,std::string> >::iterator l1it = l1.begin();
l1it != l1.end();
++l1it)
{
// look for the element with the same key in l2
// l1it->first is the key form l1
std::map<std::string, std::string>::iterator l2it = l2map.find(l1it->first);
if (l2it != l2map.end()) {
// found, then compare
if (l1it->second != l2it->second) { // l1it->second is the value from l1
// mismatch
}
} else {
// not in l2
}
}
您可以使用带有先决条件的std::mismatch
:两个列表中的所有设置都以相同的顺序出现(如果不是这样,您可以进行排序)
auto iterPair = std::mismatch(l1.begin(), l1.end(), l2.begin());
while (iterPair.first != l1.end()) {
// TODO: Handle the mismatching iterators
iterPair = std::mismatch(iterPair.first + 1, l1.end(), iterPair.second + 1);
}
如果列表中的键的顺序与示例中的相同,则可以线性遍历列表:
std::ostringstream s;
std:list<std::pair<string, string>>::const_iterator i2(outputList2.cbegin());
for(auto const &pair: outputList1) {
if(pair.second != i2->second) {
s << pair.first << ": " << pair.second << " != " << i2->second << endl;
}
++i2;
}
或者,使用STL算法:
#include <algorithm>
typedef std::list<std::pair<std::string, std::string>> List;
std::ostringstream s;
for(
auto itrs(
std::mismatch(
outputList1.cbegin(), outputList1.cend(), outputList2.cbegin()
, [](auto const &l, auto const &r){ return l.second == r.second; }))
; itrs.first != outputList1.cend()
; itrs = std::mismatch(itrs.first, outputList1.cend(), itrs.second
, [](auto const &l, auto const &r){ return l.second == r.second; }))
{
s << itrs.first->first << ": "
<< itrs.first->second << " != " << itrs.second->second
<< std::endl;
}
- 从嵌套在std::映射中的std::列表中删除元素的最佳方式
- 将std ::列表附加到std ::列表的向量中
- STD ::列表对其分配器参数有什么作用
- swig-包装到c#时,没有默认的std ::列表,我该怎么做
- 调用具有std ::列表为参数的C 函数
- STD ::列表和垃圾收集算法
- 低于20亿的质量 - 使用STD ::列表阻碍性能
- C 按其值对object的std ::列表进行排序
- 如何在(C )构造函数参数列表中包含std:列表
- 如何使用迭代器插入std ::列表
- C STD ::列表分割故障
- 将带有指针的 STD 列表复制到另一个带有指针的 STD 列表
- 比较std::对的2个std::列表
- 在 std 列表中查找对象并将其添加到另一个列表
- 与内存堆有关的C 链接列表(STD ::列表)是否使用新的
- 使用STD ::列表作为循环列表安全吗?
- C++当类型T需要构造函数时,是否可以创建类型T的std::列表
- 从对象指针的 STD 列表中擦除对象
- 如何从std::列表中删除项目
- 正在从std::unique_pointer的std::列表中删除元素