STL算法详解:for_each与transform应用

版权申诉
0 下载量 26 浏览量 更新于2024-08-08 收藏 37KB DOCX 举报
"这篇文章除了介绍STL中的for_each和transform算法,还通过示例展示了它们在实际编程中的应用。" 在C++标准模板库(STL)中,算法是处理容器内元素的重要工具。`for_each` 和 `transform` 是两个常用的算法,它们分别用于遍历容器并执行特定操作以及将一种形式的数据转换为另一种形式。 **for_each 算法** `for_each` 的主要功能是对容器中的每个元素应用一个函数或函数对象。它接受三个参数:一个指向容器开始的迭代器,一个指向容器结束的迭代器,以及一个单参数的函数对象。函数对象会在每次迭代时被调用,其参数是当前元素的引用。`for_each` 不返回任何有意义的值,通常用于执行副作用,例如打印元素、修改元素或者计数等操作。 例如,在提供的代码示例中,`PrintV` 结构体定义了一个函数对象,`operator()` 会增加一个私有变量 `count` 的值并将元素值加一,然后输出。`for_each` 被用来遍历一个整数向量 `v`,并将 `PrintV` 对象作为操作函数。这使得每个元素都被加一并打印,同时记录了操作的次数。 **transform 算法** `transform` 函数则更加复杂,它可以将一个序列中的元素转换为另一个序列。它接受四个参数:两个输入迭代器分别表示源序列的起始和结束,一个输出迭代器表示目标序列的起始,以及一个函数或函数对象,这个对象定义了如何将源序列的元素转换为目标序列的元素。 例如,如果要将一个包含整数的向量转换为其平方,可以使用 `transform` 和 `multiplies` 函数对象: ```cpp #include <numeric> vector<int> source = { 1, 2, 3, 4 }; vector<int> destination(source.size()); transform(source.begin(), source.end(), destination.begin(), multiplies<int>()); ``` 在这个例子中,`transform` 会将 `source` 中的每个元素与自身相乘(因为 `multiplies<int>()` 是二元操作),结果存储到 `destination` 向量中。 总结起来,`for_each` 和 `transform` 是C++ STL 中用于处理容器元素的两个重要算法。`for_each` 适用于执行无返回值的单个元素操作,而 `transform` 则用于将源序列转换为目标序列,通常涉及某种计算或类型转换。理解并熟练运用这些算法能够极大地提高代码的效率和可读性。

加速这一段代码#include <thread> #include <mutex> // 用于保护m_vpdEdgePoints和m_vdEdgeGradient的锁 std::mutex g_mutex; void process_edges(const cv::Mat& RoiMat, const std::vector<cv::Point2d>& m_vpdEquinoxPoints, const double m_dMeasureLength, const double m_dMeasureHeight, const double m_dSigma, const int m_nThresholdCircle, const int m_nTranslationCircle, const std::vector<double>& m_vdMeasureAngle, std::vector<cv::Point2d>& m_vpdEdgePoints, std::vector<double>& m_vdEdgeGradient, int start_idx, int end_idx, Extract1DEdgeCircle Extract1DEdgeCircle) { std::vector<Edge1D_Result> edges; for (int i = start_idx; i < end_idx; i++) { edges = Extract1DEdgeCircle.Get1DEdge(RoiMat, m_vpdEquinoxPoints[i], m_dMeasureLength, m_dMeasureHeight,m_vdMeasureAngle[i], m_dSigma, m_nThresholdCircle, m_nTranslationCircle == 1 ? Translation::Poisitive : Translation::Negative, Selection::Strongest); // 使用锁保护m_vpdEdgePoints和m_vdEdgeGradient //std::lock_guard<std::mutex> lock(g_mutex); for (int j = 0; j < edges.size(); j++) { m_vpdEdgePoints.push_back(edges[j].m_pdEdgePoint); m_vdEdgeGradient.push_back(edges[j].m_dGradient); } } } const int num_threads = 10; std::vector<std::thread> threads(num_threads); std::vector<std::vector<cv::Point2d>> edge_points(num_threads); std::vector<std::vector<double>> edge_gradients(num_threads); for (int i = 0; i < num_threads; i++) { int start_idx = i * m / num_threads; int end_idx = (i + 1) * m / num_threads; threads[i] = std::thread(process_edges, std::ref(RoiMat), std::ref(m_vpdEquinoxPoints), m_dMeasureLength, m_dMeasureHeight, m_dSigma, m_nThresholdCircle, m_nTranslationCircle, std::ref(m_vdMeasureAngle), std::ref(edge_points[i]), std::ref(edge_gradients[i]), start_idx, end_idx, Extract1DEdgeCircle); } for (int i = 0; i < num_threads; i++) { threads[i].join(); // 合并结果 m_vpdEdgePoints.insert(m_vpdEdgePoints.end(), edge_points[i].begin(), edge_points[i].end()); m_vdEdgeGradient.insert(m_vdEdgeGradient.end(), edge_gradients[i].begin(), edge_gradients[i].end()); }

2023-05-25 上传