如何对已排序的std::vector元组去重,求和第三项生成新vector?
解决方案
一、循环遍历实现
这种方式直观直接,容易理解,适合快速实现需求:
#include <vector> #include <tuple> #include <iostream> int main() { std::vector<std::tuple<int, int, double>> triplets = { {0, 0, 1}, {1, 2, 5}, {2, 2, 1}, {2, 2, 3}, {3, 0, 2}, {4, 4, 2}, {4, 4, 5}, {5, 5, 6} }; std::vector<std::tuple<int, int, double>> triplets_new; if (triplets.empty()) return 0; // 先拿第一个元素作为当前合并项 auto current = triplets[0]; for (size_t i = 1; i < triplets.size(); ++i) { const auto& elem = triplets[i]; // 对比前两个元素是否一致 if (std::get<0>(elem) == std::get<0>(current) && std::get<1>(elem) == std::get<1>(current)) { // 一致就累加第三项 std::get<2>(current) += std::get<2>(elem); } else { // 不一致就把当前合并项存入结果,更新当前项 triplets_new.push_back(current); current = elem; } } // 别忘了把最后一个合并项加进去 triplets_new.push_back(current); // 验证输出(可删) for (const auto& t : triplets_new) { std::cout << "{" << std::get<0>(t) << ", " << std::get<1>(t) << ", " << std::get<2>(t) << "}\n"; } return 0; }
二、STL算法实现
用std::accumulate配合lambda表达式,更贴合STL的编程风格:
#include <vector> #include <tuple> #include <numeric> #include <iostream> int main() { std::vector<std::tuple<int, int, double>> triplets = { {0, 0, 1}, {1, 2, 5}, {2, 2, 1}, {2, 2, 3}, {3, 0, 2}, {4, 4, 2}, {4, 4, 5}, {5, 5, 6} }; std::vector<std::tuple<int, int, double>> triplets_new; if (triplets.empty()) return 0; // 从第二个元素开始累加处理 std::accumulate(std::next(triplets.begin()), triplets.end(), triplets[0], [&triplets_new](auto current, const auto& elem) { if (std::get<0>(elem) == std::get<0>(current) && std::get<1>(elem) == std::get<1>(current)) { std::get<2>(current) += std::get<2>(elem); return current; } else { triplets_new.push_back(current); return elem; } }); // 存入最后一组合并结果 triplets_new.push_back(triplets.back()); // 验证输出(可删) for (const auto& t : triplets_new) { std::cout << "{" << std::get<0>(t) << ", " << std::get<1>(t) << ", " << std::get<2>(t) << "}\n"; } return 0; }
关键注意点
- 题目里已经说明原容器是按第一个元素排序的,且相同第一个元素的项第二个元素也一致,所以两种方案都能正常工作。如果原容器未排序,必须先做排序:
std::sort(triplets.begin(), triplets.end(), [](const auto& a, const auto& b) { if (std::get<0>(a) != std::get<0>(b)) { return std::get<0>(a) < std::get<0>(b); } return std::get<1>(a) < std::get<1>(b); });
内容的提问来源于stack exchange,提问作者user12422568
相关产品推荐
相关产品推荐

