使用算法查找自定义数据向量的最大值和最小值

时间:2017-10-09 15:42:46

标签: c++ c++11 stl-algorithm

我有这样的数据结构:

library("EBImage")

# Load Image
  nuc <- readImage(system.file("images", "nuclei.tif", package="EBImage"))
# Segmented Image
  nucbw <- bwlabel(nuc > 0.5)
# Create empty dataframe
  data <- data.frame()
# Compute for each frame
  for (i in 1:numberOfFrames(nuc)){
    # Create cell column to identify each cell
      if (i == 1){
        cell <- 1:max(nucbw[,,i])
        } else {
          cell <- (max(nucbw[,,(i-1)]) + 1) : (max(nucbw[,,i]) + max(nucbw[,,(i-1)]))
          }
    # Create frame column to know the frame where each cell belongs
      frame <- rep(paste("Frame", i, sep = ""), max(nucbw[,,i]))
    # Create de features dataframe  
      x <- computeFeatures.basic(nucbw[,,i], nuc[,,i])
    # Binding dataframe for each frame
      comb <- cbind(cell, frame, x)
    # Binding dataframe different frame  
      data <- rbind(data, comb)
     }
data

现在我想画这个矢量。要创建一个漂亮的轴,我想在此向量中找到数据的最大值和最小值。我确实喜欢这个,但显然,因为它仅基于struct Speed { int set; //set by user int act; //actual speed int millis; //millis since epoch } vector<Speed> data; ,如果set小于或大于act,则会失败。我的意思是图表的set轴应介于Y的最小值和set, act的最小值之间。

set, act

**我知道**如何编写一个不涉及算法和lambdas的普通代码来实现结果......但是我很想知道如何使用算法/ lambda来完成算法/ lambda没有在结构中运算符重载

我也可以为auto max = std::max_element(begin(data), end(data), [&](const Speed& a, const Speed& b){ return a.set() < b.set(); //how about act? }); auto min = std::min_element(begin(data), end(data), [&](const Speed& a, const Speed& b){ return a.set() < b.set(); //how about act? }); 做同样的事情,然后比较结果......但这会花费我4个循环!

2 个答案:

答案 0 :(得分:2)

您可以在std::minstd::max次调用中使用std::min_elementstd::max_element

#include <algorithm>
#include <iostream>
#include <vector>

struct Speed {
       int set;
       int act;
       int millis;
};

int main() {
    std::vector<Speed> data = {
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
    };

    auto max_val = std::max_element(begin(data), end(data),
                                    [](const Speed& a, const Speed& b){
        return std::max(a.set, a.act) < std::max(b.set, b.act);
    });

    auto min_val = std::min_element(begin(data), end(data),
                                    [](const Speed& a, const Speed& b){
        return std::min(a.set, a.act) < std::min(b.set, b.act);
    });

    std::cout << "MAX: " << max_val->set << " " << max_val->act << "\n";
    std::cout << "MIN: " << min_val->set << " " << min_val->act << "\n";
}

使用std::minmax的单一通行证无法真正起作用。每个元素的比较必须返回一个布尔值,其中true表示左侧小于右侧,false表示左侧大于或等于右侧(即需要严格的弱排序)。但是,这里单个元素可以比小于另一个元素。您可以轻松编写自己的函数来生成单次传递minmax_element,但我认为它不适合现有的STL函数而不进行两次传递。

答案 1 :(得分:2)

一般来说,我会推荐最易读的代码。

因此,它会像(假设至少有一个项目):

auto set_minmax = std::minmax_element(begin(data), end(data),
    [&](const Speed& a, const Speed& b) { return a.set < b.set; });

auto act_minmax = std::minmax_element(begin(data), end(data),
    [&](const Speed& a, const Speed& b) { return a.act < b.act; });

auto min_act_set = std::min(*set_minmax.first, *act_minmax.first);
auto max_act_set = std::max(*set_minmax.second, *act_minmax.second);

但是,如果数据非常大或逻辑比较复杂,我建议有一个对象来累积统计数据并对数据进行某种循环。