使用 STL/Boost 查找和修改向量中的匹配元素
假设我有一个这样声明的向量:
struct MYSTRUCT
{
float a;
float b;
};
std::vector<MYSTRUCT> v;
现在,我想找到 v 中共享相同 a 的所有元素,并对它们的 b 求平均值,即
说 v 包含这五个元素 {a, b}: {1, 1}, {1, 2}, {2, 1}, {1, 3}, {2, 2}
我想得到 v[0], v[1], v[3] (其中 a 为 1) 和平均值 b :(1 + 2 + 3)/3 = 2,v[2]和v[4](其中a为2)和平均值b:(1+2)/2 = 1.5
之后v将如下所示:{ 1, 2}, {1, 2}, {2, 1.5}, {1, 2}, {2, 1.5}
我对 STL 或 Boost 不太熟悉,所以我只能弄清楚如何做到这一点C++ 中的“bruteforce”方式,但我猜测 STL(for_each?)和 Boost(lambda?)库可以更优雅地解决这个问题。
编辑仅供参考,这是我的(工作)强力方法:
for(int j = 0; j < tempV.size(); j++)
{
MYSTRUCT v = tempV.at(j);
int matchesFound = 0;
for(int k = 0; k < tempV.size(); k++)
{
if(k != j && v.a == tempV.at(k).a)
{
v.b += tempV.at(k).b;
matchesFound++;
}
}
if(matchesFound > 0)
{
v.b = v.b/matchesFound;
}
finalV.push_back(v);
}
Let's say I have a vector declared like this:
struct MYSTRUCT
{
float a;
float b;
};
std::vector<MYSTRUCT> v;
Now, I want to find all elements of v that share the same a, and average their b, i.e.
Say v contains these five elements {a, b}: {1, 1}, {1, 2}, {2, 1}, {1, 3}, {2, 2}
I want to get v[0], v[1], v[3] (where a is 1) and average b: (1 + 2 + 3)/3 = 2, and v[2] and v[4] (where a is 2) and average b: (1+2)/2 = 1.5
Afterwards v will look like this: {1, 2}, {1, 2}, {2, 1.5}, {1, 2}, {2, 1.5}
I'm not really familiar with STL or Boost so I can only figure out how to do this the "bruteforce" way in C++, but I'm guessing that the STL (for_each?) and Boost (lambda?) libraries can solve this more elegantly.
EDIT Just for reference, here's my (working) brute force way to do it:
for(int j = 0; j < tempV.size(); j++)
{
MYSTRUCT v = tempV.at(j);
int matchesFound = 0;
for(int k = 0; k < tempV.size(); k++)
{
if(k != j && v.a == tempV.at(k).a)
{
v.b += tempV.at(k).b;
matchesFound++;
}
}
if(matchesFound > 0)
{
v.b = v.b/matchesFound;
}
finalV.push_back(v);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
只是大声思考,这可能会变得相当愚蠢:
嗯。不完全愚蠢,但也许也不引人注目......
Just thinking aloud, this may end up fairly silly:
Hmm. Not completely silly, but perhaps not compelling either...
解决方案的草图:
不过,这不是一个很好的解决方案,因为它不完全是所要求的(感谢排序),而且对我来说仍然感觉不太干净。我认为一些filter_iterators和transform_iterators或其他东西可能会给出更加函数式的答案。
Sketch of a solution:
It's not a great one, though, since it's not exactly what was asked for (thanks to the sort), and still doesn't really feel clean to me. I think that some filter_iterators and transform_iterators or something could possibly give a much more functional-style answer.
另一种方法,虽然我认为它在时间复杂性方面渐近相同,但这种方法并不到位。
不过,这只是一种稍微优雅的暴力解决方案编码方式,而不是一种很好的函数式方式。
Another approach, this one not in-place, though I think it's time-complexity-wise asymptotically the same.
Again, though, it's just a slightly elegant way to code the brute-force solution, not a nice functional-style way.
也许是一种蛮力方法?...
我已经用您提供的值对此进行了测试并获得了所需的向量 - 这并不完全是最佳的,但我认为它很容易遵循(可能比复杂的算法更可取) 。
Perhaps a brute force approach?...
I've tested this with the values you've supplied and get the required vector - It's not exactly optimal, but I think it's quite easy to follow (might be more preferable to a complex algorithm).
避免C风格!这不是 C++ 的设计目的。我想强调清晰度和可读性。
Avoid C-style! It's not what C++ is designed for. I'd like to emphasize clarity and readability.
您可以将“分区”算法与“累积”一起使用。
示例文档
gcc 标头中的
You can use the "partition" algorithm along with "accumulate."
Example
Documentation from the gcc headers
似乎最简单的方法是在集合上运行一个中等复杂的函子:
It seems the easiest way is to run a moderately complex functor over the colelction:
编写C++ 时,您应该在可重用性(例如重用现有算法和数据结构)和可读性之间保持平衡。 onebyone 很接近,但他的解决方案可以进一步改进:
拥有可重用的“平均”类型的奖励积分。
Writing C++, you should maintain balance between reusability (e.g. reuse existing algorithms and data structures) and readability. onebyone was close, but his solution can be further improved:
Bonus points for having reusable "average" type.