2

我计划对 std::vector 数组的每个数据执行操作,如下代码所示:

std::vector<int> abc;
abc.push_back(1);
abc.push_back(5);
abc.push_back(2);
std::sort(abc);
int min = abc[0];
int max = abc[2];
for(int i=0; i<3; i++)
  abc[i] = (abc[i]-min)/(max-min);

我现在的问题是我是否有更优雅的表演方式

 for(int i=0; i<3; i++)
      abc[i] = (abc[i]-min)/(max-min)

withfor_each , trasnform或 stl 中的其他方法。我对这些函数的困难在于我不知道如何在它们中加入外部参数。

4

3 回答 3

4

这是一个for_each用于更新每个元素的示例abc

std::for_each(abc.begin(),    // Start of range
              abc.end(),      // End of range
              [=](int &value) // The operation to apply
              {
                value=(value-min)/(max-min);
              });

for_each尽管可以for_each保证遍历的顺序以及每个元素发生多少次调用,但通常不赞成更改被迭代的序列。但是,为了安抚反对者,您可能希望使用transform没有这样的保证(遍历顺序和谓词调用次数,除了通过复杂性保证之外){注意:复杂性已修改为C++11 中调用次数的保证,见 25.3.4.4}):

std::transform(abc.begin(),    // Start of source range
               abc.end(),      // End of source range
               abc.begin(),    // Start of destination range
               [=](int value)  // The operation to apply
               {
                 return (value-min)/(max-min);
               });

顺便说一句,由于您在公式中进行整数除法,因此您必须非常小心结果的截断。您可能还应该检查除以零。

于 2013-08-14T14:10:17.200 回答
4

使用 C++11,您可以使用捕获所需变量的 lambda:

std::transform(std::begin(abc), std::end(abc),
               std::begin(abc),
               [=](int x) { return (x-min)/(max-min); });

这等效于您的循环,尽管您可能希望首先验证逻辑是否正确。

于 2013-08-14T14:11:19.573 回答
4

这很容易通过使用std::transform合适的仿函数来实现。在这里,为了简洁起见,使用了 lambda:

std::transform(std::begin(abc), 
               std::end(abc),
               std::begin(abc), 
               [&](int i) { return (i-min)/(max-min); }); 

目前尚不清楚这是否是一种改进。我只想写一个普通的基于范围的循环:

for(int& i : abc)
  i = (i-min)/(max-min);
于 2013-08-14T14:11:37.837 回答