【问题标题】:How to multiply a vector and scalar in C++?如何在 C++ 中将向量和标量相乘?
【发布时间】:2016-12-08 02:43:49
【问题描述】:

我想将一个向量与一个标量相乘。这个向量是使用我的this question 接受的答案创建的,即:

std::vector<int> n(N + 1);
  std::iota(begin(n), end(n), 0);

我想将这个向量n 与一个名为npi 的标量(特别是双精度类型,如果它与此处相关)相乘。

我在这里看到了this answer 的上一个问题,但这并没有那么有帮助。我尝试实现它的方式是添加:

std::transform(n.begin(), n.end(), n.begin(),
           std::bind1st(std::multiplies<T>(),pin));

到我的 C++ 程序。这返回了编译错误:

error: ‘T’ was not declared in this scope
                std::bind1st(std::multiplies<T>(),pin));

我想调用通过将此向量乘以标量 npi 所创建的向量,因此请不要给我将调用此新向量 n 的代码(即覆盖我现有的 n 向量)。

编辑:

如果它会安抚投票结束这个问题的人,这是我的完整程序:

#include <iostream>
#include <vector>
#include <string>
#include <fstream>
#include <cmath>
#include <utility>
#include <unistd.h>
#include <algorithm>
#include <numeric>
/*#include <armadillo>*/

using namespace std;
/*using namespace arma;*/

double N  = 1000.0;
double x0 = 0;
double x1 = 100;
double pin = M_PI / double(N);

int main() {
  std::vector<int> n(N + 1);
  std::iota(begin(n), end(n), 0);
  std::transform(n.begin(), n.end(), n.begin(),
               std::bind1st(std::multiplies<T>(),pin));
  for(double i: n)
  {
    std::cout << i << '\n' << std::scientific;
  }
}

【问题讨论】:

  • 你的向量是整数。如果将其乘以双标量,则向量中的值仍为 int - 目标向量需要为双精度,因此如果您要就地修改,请将 vector 更改为 vector
  • double(N) 是 C 风格的演员表。最好尽可能避免强制转换(这里不需要,因为 N 已经是双精度数了)。如果有必要,最好使用 C++ 风格的static_cast&lt;double&gt;(N)
  • 认为 begin(foo)foo.begin() 总是等价的(虽然不确定),在这种情况下最好始终坚持一种风格。这是一个非常次要且可能过于迂腐的观点,但一致性使代码更清晰!
  • N 已经是双精度数,因此不需要强制转换。
  • 请澄清npi 应该是什么--vector&lt;int&gt;vector&lt;double&gt; 或其他?您现有的代码尝试就地修改n(因此提供vector&lt;int&gt; 输出)。

标签: c++ vector


【解决方案1】:

对于vector&lt;int&gt; 输出,一种方法是:

auto npi = n;

for( auto& i: npi )
    i *= pin;

如果npi 应该是vector&lt;double&gt;(从问题中不清楚),那么将第一行替换为:

std::vector<double> npi( n.begin(), n.end() );

【讨论】:

  • 如果 OP 想要一个 vector&lt;int&gt; 但 OP 想要一个 vector&lt;double&gt; 作为输出,这将起作用。否则,这是非常简洁的!
  • @JackDeeth OP 没有说他想要vector&lt;double&gt; 输出。并且他的原始代码尝试就地进行转换,这表明他打算将vector&lt;int&gt; 输出;尽管他在 cmets 中说他不想覆盖原始向量。
  • @MM 我没有想到int a = int b * double c 可能是一个有用的东西。好电话!
  • @JackDeeth 你可能是对的,但我可以想象一些整数结果的应用(例如,在格子上工作而不是连续空间)
【解决方案2】:

您需要将T 替换为向量中包含的类型,在本例中为int。但是,您可能可以通过在此处使用 lambda 函数来简化代码:

#include <algorithm> // for std::transform
#include <cmath>     // for M_PI
#include <iostream>  // for std::cout etc
#include <numeric>   // for std::iota
#include <vector>    // for awesome

int main() {
  std::vector<int> vec1(10);
  std::iota(vec1.begin(), vec1.end(), 0);

  int N = 42;

  std::vector<double> vec2(vec1.size()); // vec2 needs to be as big or bigger than vec1

  std::transform(vec1.begin(), vec1.end(), vec2.begin(),
                 [N](int i) { return i * M_PI / N; });

  for (auto a : vec1)
    std::cout << a << " ";
  std::cout << std::endl;

  for (auto a : vec2)
    std::cout << a << " ";
  std::cout << std::endl;
}

这是一个在线示例:http://melpon.org/wandbox/permlink/XrNxDND0steJmym8

【讨论】:

  • 这会将结果存储为n(因此会覆盖我的n 向量)吗?
  • 是的,这会。可能有一种方法可以将std::transform 的输出写入一个新的向量,不过......等待......
  • 是否还值得注意pin 不是整数?它是pi/N,其中 N 是一个整数。那不是说应该使用double这个类型吗?
  • 没问题 - 我已经扩展了这个例子。不过,您可能不需要使用std::bind1st(std::multiplies
【解决方案3】:

如果我对您的理解正确,您需要以下内容

std::vector<double> v;
v.reserve(n.size());

std::transform(n.begin(), n.end(), std::back_inserter( v ),
    std::bind1st(std::multiplies<double>(), pin));

【讨论】:

    【解决方案4】:

    您可以在 Lambda 函数的捕获子句中传递标量,并在 Lambda 函数本身内部进行乘法运算

        #include <algorithm>
        #include <vector>
        
        std::vector<int> foo; 
        std::vector<int> bar;
        auto npi=4.0;
        std::transform (foo.begin(), foo.end(), bar.begin(), foo.begin(), [&npi](auto& c){return c * npi;}
    

    【讨论】:

      猜你喜欢
      • 2021-01-20
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-11-24
      • 1970-01-01
      相关资源
      最近更新 更多