我目前正在尝试显示总数。基于名称的topicids和testids。
但是我在做那个显示时遇到了麻烦。我最初有一个包含所有数据的 vector 。
例如
user1:name:topic1:test1
user1:name:topic2:test1
user2:name:topic1:test1
user2:name:topic2:test1
由于vector中有多个重复项,我想以如下格式显示:
用户名:姓名:numofTopics:numofTests
用户 1:名称:2:2
用户 1:名称:2:2
因此,我想到将该名称与 vector 中的下一个名称进行比较,并将该元素插入一个名为 singleAcc 的新 vector 。这样做的目的是将重复元素显示为 ONE 元素。
下面是我显示数据的代码
vector<AccDetails> singleAcc;
for (vector<AccDetails>::iterator itr=accInfo.begin();itr!=accInfo.end()-1; ++itr) {
if (itr->name == itr[1].name) {
//cout << (*itr) << endl;
singleAcc.push_back(*itr);
}
}
for (vector<AccDetails>::iterator itr = singleAcc();itr!=singleAcc();++itr) {
cout << left
<< setfill(' ')
<< setw(20) << itr[0].username
<< setw(20) << itr[0].name
<< setw(20) << countTopics(itr->name)
<< setw(20) << countTests()
<< endl;
}
问题:
在第一次 vector 迭代中,名称不会与 accDetails.end()-1
的最后一个元素 bcoz 进行比较。
如何将重复的元素显示为ONE 元素?我在第二次迭代中所做的是正确的吗?
希望有人能帮我解决这个问题。或者有更好的方法吗? 谢谢!
最佳答案
为什么这行不通
您提出的解决方案根本无法按预期工作。考虑在连续子序列中被认为是重复的三个元素(我使用数字来简化概念):
[1,1,1]
- 迭代器会先比较
1
和1
,然后push_back
第一个。 - 然后它将second
1
与第三个进行比较,它再次返回 true,并且应该没有重复的结果结束了:
[1,1]
所以这显然不是你想做的事情。总的来说,这看起来像是一个相当奇怪的问题,但是为了解决您在此处发布的这一部分,我建议使用 std::multiset
。
更好的解决方案
创建一个比较器来测试 name
字段,就像您在此处所做的那样。
然后,恢复唯一字段就相当简单了:
std::multiset<AccDetail> s;
for (auto element_it = s.begin(); element_it != s.end(); element_it = s.upper_bound(*element_it)) {
auto er = s.equal_range(*element_it);
// use this to get all the elements with given name
for (auto i = er.first; i != er.second; ++i)
cout << *i << " ";
// use this to get the number of them
cout << std::distance(er.first, er.second);
}
参见 a working sample在 Coliru 上。
奖金
你是对的,第一个循环中的迭代器会越界。解决方案相当简单:zip 迭代器 可以自动处理。
for (auto elem_pair : zip(v, v | drop(1)))
if (elem_pair.first == elem_pair.second)
...
Boost.Range 具有允许该代码工作的工具。不过,它仍然会遇到我提到的问题。
关于c++ - 显示基于 1 种类型的结构 vector 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18007153/