48

嗨,我想通过标量值(乘、加等)向量,例如myv1 * 3,我知道我可以用 forloop 做一个函数,但是有没有办法使用 STL 函数来做到这一点?{Algorithm.h :: 变换函数}之类的东西?

4

6 回答 6

94

是的,使用std::transform

std::transform(myv1.begin(), myv1.end(), myv1.begin(),
               std::bind(std::multiplies<T>(), std::placeholders::_1, 3));

在 C++17 之前,您可以使用std::bind1st(),它在 C++11 中已被弃用。

std::transform(myv1.begin(), myv1.end(), myv1.begin(),
               std::bind1st(std::multiplies<T>(), 3));

对于占位符;

#include <functional> 
于 2010-10-07T19:22:45.970 回答
27

如果您可以使用 avalarray而不是 a vector,则它具有用于进行标量乘法的内置运算符。

v *= 3;

如果你必须使用 a vector,你确实可以使用transform来完成这项工作:

transform(v.begin(), v.end(), v.begin(), _1 * 3);

(假设您有类似于Boost.Lambda的东西,可以让您轻松创建匿名函数对象,例如_1 * 3:-P)

于 2010-10-07T19:22:18.210 回答
23

您的问题的现代 C++ 解决方案。

std::vector<double> myarray;
double myconstant{3.3};
std::transform(myarray.begin(), myarray.end(), myarray.begin(), [&myconstant](auto& c){return c*myconstant;});
于 2019-01-20T18:54:05.857 回答
1

我认为for_each当您想要遍历向量并根据某种模式操作每个元素时非常合适,在这种情况下,一个简单的 lambda 就足够了:

std::for_each(myv1.begin(), mtv1.end(), [](int &el){el *= 3; });

请注意,您想要捕获以供 lambda 函数使用的任何变量(例如,您想要与某个预定的标量相乘),都会作为参考放入括号中。

于 2018-01-03T10:43:58.810 回答
0

如果您必须将结果存储在一个新的 vector中,那么您可以使用std::transform()来自<algorithm>标头的:

#include <algorithm>
#include <vector>

int main() {
    const double scale = 2;
    std::vector<double> vec_input{1, 2, 3};
    std::vector<double> vec_output(3); // a vector of 3 elements, Initialized to zero
    // ~~~
    std::transform(vec_input.begin(), vec_input.end(), vec_output.begin(),
                   [&scale](double element) { return element *= scale; });
    // ~~~
    return 0;
}

所以,我们在这里要说的是,

  • 取从开头 ( ) 到结尾 ( )的值 ( elements) , vec_inputvec_input.begin()vec_input.begin()
    • 本质上,使用前两个参数,您可以指定[beginning, end)要转换的元素范围 ( ),范围
  • 将每个传递element给最后一个参数 lambda 表达式,
  • 将 lambda 表达式的输出vec_output从开头 ( vec_output.begin()) 放在开头。
    • 第三个参数是指定目标向量的开始。

拉姆达表达式

  • [&scale]通过引用从外部捕获比例因子 ( ) 的值,
  • 将 double 类型的向量元素作为输入(由 传递给它std::transform()
  • 在函数体中,它返回最终结果,
    • 正如我上面提到的,它将因此存储在vec_input.

最后说明:虽然没有必要,但您可以通过以下 lambda 表达式:

[&scale](double element) -> double { return element *= scale; }

它明确指出 lambda 表达式的输出是双精度数。但是,我们可以省略它,因为在这种情况下,编译器可以自己推断返回类型。

于 2021-11-16T22:18:00.060 回答
-1

I know this not STL as you want, but it is something you can adapt as different needs arise.

Below is a template you can use to calculate; 'func' would be the function you want to do: multiply, add, and so on; 'parm' is the second parameter to the 'func'. You can easily extend this to take different func's with more parms of varied types.

template<typename _ITStart, typename _ITEnd, typename _Func , typename _Value >
_ITStart xform(_ITStart its, _ITEnd ite, _Func func, _Value parm)
{
    while (its != ite) { *its = func(*its, parm); its++; }
    return its;
}
...

int mul(int a, int b) { return a*b; }

vector< int > v;

xform(v.begin(), v.end(), mul, 3); /* will multiply each element of v by 3 */

Also, this is not a 'safe' function, you must do type/value-checking etc. before you use it.

于 2010-10-07T20:54:06.703 回答