在 C++ 中计算两个向量的标量积
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10908012/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Computing the scalar product of two vectors in C++
提问by HowardRoark
I am trying to write a program with a function double_product(vector<double> a, vector<double> b)
that computes the scalar product of two vectors. The scalar product is
我正在尝试编写一个带有double_product(vector<double> a, vector<double> b)
计算两个向量标量积的函数的程序。标量积是
$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.
Here is what I have. It is a mess, but I am trying!
这是我所拥有的。这是一团糟,但我正在努力!
#include <iostream>
#include <vector>
using namespace std;
class Scalar_product
{
public:
Scalar_product(vector<double> a, vector<double> b);
};
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
int main() {
cout << product << endl;
return 0;
}
回答by Jerry Coffin
Unless you need to do this on your own (e.g., writing it is homework), you should really use the standard algorithm that's already written to do exactly what you want:
除非你需要自己做这件事(例如,写它是家庭作业),你真的应该使用已经写好的标准算法来做你想做的事:
#include <iostream>
#include <numeric>
#include <vector>
int main() {
std::vector<double> a {1, 2, 3};
std::vector<double> b {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(std::begin(a), std::end(a), std::begin(b), 0.0);
return 0;
}
Note that while begin(a)
and end(a)
are new in C++11, std::inner_product
has been available since C++98. If you are using C++ 98 (or 03), it's pretty easy to write your own equivalent of begin
and end
to work with arrays though:
请注意,whilebegin(a)
和end(a)
是 C++11 中的新内容,std::inner_product
自 C++98 以来已可用。如果您使用的是 C++ 98(或 03),则编写自己的等效数组begin
并end
使用数组非常容易:
template <class T, size_t N>
T *begin(T (&array)[N]) {
return array;
}
template <class T, size_t N>
T *end(T (&array)[N]) {
return array + N;
}
Using these, a C++ 98 version of the previous code could look something like this:
使用这些,先前代码的 C++ 98 版本可能如下所示:
int main() {
double a[] = {1, 2, 3};
double b[] = {4, 5, 6};
std::cout << "The scalar product is: "
<< std::inner_product(begin(a), end(a), begin(b), 0.0);
return 0;
}
Note that the begin
and end
above will only work for arrays, where the begin
and end
in C++11 (and later) will also work for normal collection types that define a .begin()
and .end()
(though it's trivial to add overloads to handle those as well, of course):
请注意,begin
与end
上述只会数组,工作在begin
和end
在C ++ 11(或更高版本)也将用于定义一个正常的集合类型的工作.begin()
和.end()
(虽然是微不足道的添加过载处理那些为好,当然) :
template <class Coll>
typename Coll::iterator begin(Coll const& c) { return c.begin(); }
template <class Coll>
typename Coll::iterator end(Coll const& c) { return c.end(); }
回答by bobobobo
You can delete the class
you have defined. You don't need it.
您可以删除class
您定义的。你不需要它。
In your scalar_product
function:
在您的scalar_product
功能中:
double scalar_product(vector<double> a, vector<double> b)
{
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
for (int i = 0; i <= b.size()-1; i++)
product = product + (a[i])*(b[i]);
return product;
}
It's almost there. You don't need 2 loops. Just one.
快到了。你不需要2个循环。只有一个。
double scalar_product(vector<double> a, vector<double> b)
{
if( a.size() != b.size() ) // error check
{
puts( "Error a's size not equal to b's size" ) ;
return -1 ; // not defined
}
// compute
double product = 0;
for (int i = 0; i <= a.size()-1; i++)
product += (a[i])*(b[i]); // += means add to product
return product;
}
Now to callthis function, you need to create 2 vector objects in your main()
, fill them with values, (the same number of values of course!) and then call scalar_product( first_vector_that_you_create, second_vector_object );
现在要调用这个函数,你需要在你的 中创建 2 个向量对象,main()
用值填充它们,(当然是相同数量的值!)然后调用scalar_product( first_vector_that_you_create, second_vector_object );
回答by Matthieu M.
While you have been presented many solutions that work, let me spin up another variation to introduce a couple of concepts that should help you writing better code:
虽然已经向您展示了许多有效的解决方案,但让我提出另一个变体来介绍一些应该可以帮助您编写更好代码的概念:
class
are only needed to pack data together- a function should check its preconditions as soon as possible, those should be documented
- a function should have postconditions, those should be documented
- code reuse is the cornerstone of maintenable programs
class
只需要将数据打包在一起- 一个函数应该尽快检查它的先决条件,那些应该被记录下来
- 一个函数应该有后置条件,这些应该被记录在案
- 代码重用是可维护程序的基石
With that in mind:
考虑到这一点:
// Takes two vectors of the same size and computes their scalar product
// Returns a positive value
double scalar_product(std::vector<double> const& a, std::vector<double> const& b)
{
if (a.size() != b.size()) { throw std::runtime_error("different sizes"); }
return std::inner_product(a.begin(), a.end(), b.begin(), 0.0);
} // scalar_product
You could decide to use the inner_product
algorithm directly but let's face it:
您可以决定inner_product
直接使用该算法,但让我们面对现实:
- it requires four arguments, not two
- it does not check for its arguments being of the same size
- 它需要四个参数,而不是两个
- 它不检查其参数是否具有相同的大小
so it's better to wrap it.
所以最好把它包起来。
Note: I used const&
to indicate to the compiler not to copy the vectors.
注意:我曾经const&
向编译器指示不要复制向量。
回答by Ankit
Here is the code that you should have. I see you have used class in your code, which you do not really need here. Let me know if the question required you to use class.
这是您应该拥有的代码。我看到您在代码中使用了 class,而您在这里并不真正需要它。如果问题要求您使用课程,请告诉我。
As you are new and this code might scare you. So, I will try to explain this as I go. Look for comments in the code to understand what is being done and ask if you do not understand.
由于您是新手,因此此代码可能会吓到您。所以,我会在我走的时候尝试解释这一点。在代码中查找注释以了解正在执行的操作并询问您是否不明白。
//Scalar.cpp
#include <stdlib.h>
#include <iostream>
#include <vector>
using namespace std;
/**
This function returns the scalar product of two vectors "a" and "b"
*/
double scalar_product(vector<double> a, vector<double> b)
{
//In C++, you should declare every variable before you use it. So, you declare product and initialize it to 0.
double product = 0;
//Here you check whether the two vectors are of equal size. If they are not then the vectors cannot be multiplied for scalar product.
if(a.size()!=b.size()){
cout << "Vectors are not of the same size and hence the scalar product cannot be calculated" << endl;
return -1; //Note: This -1 is not the answer, but just a number indicating that the product is not possible. Some pair of vectors might actually have a -1, but in that case you will not see the error above.
}
//you loop through the vectors. As bobo also pointed you do not need two loops.
for (int i = 0; i < a.size(); i++)
{
product = product + a[i]*b[i];
}
//finally you return the product
return product;
}
//This is your main function that will be executed before anything else.
int main() {
//you declare two vectors "veca" and "vecb" of length 2 each
vector<double> veca(2);
vector<double> vecb(2);
//put some random values into the vectors
veca[0] = 1.5;
veca[1] = .7;
vecb[0] = 1.0;
vecb[1] = .7;
//This is important! You called the function you just defined above with the two parameters as "veca" and "vecb". I hope this cout is simple!
cout << scalar_product(veca,vecb) << endl;
}
If you are using an IDE then just compile and run. If you are using command-line on a Unix-based system with g++ compiler, this is what you will do (where Scalar.cpp is the file containing code):
如果您使用的是 IDE,则只需编译并运行即可。如果您在带有 g++ 编译器的基于 Unix 的系统上使用命令行,这就是您要做的(其中 Scalar.cpp 是包含代码的文件):
g++ Scalar.cpp -o scalar
To run it simply type
要运行它,只需键入
./scalar
You should get 1.99
as the output of the above program.
你应该得到1.99
上述程序的输出。
回答by jakebird451
You seem to want to make a class specifically for vectors. The class I made in my example is tailored to 3 dimensional vectors, but you can change it to another if desired. The class holds i,j,k but also can conduct a scalar products based on other MathVectors. The other vector is passed in via a C++ reference. It is hard to deduce what the question was, but I think this might answer it.
您似乎想专门为向量创建一个类。我在示例中创建的类是为 3 维向量量身定制的,但如果需要,您可以将其更改为另一个。该类包含 i,j,k,但也可以进行基于其他 MathVectors 的标量积。另一个向量通过 C++ 引用传入。很难推断出问题是什么,但我认为这可能会回答它。
#include <iostream>
using namespace std;
class MathVector
{
private:
double i,j,k;
public:
MathVector(double i,double j,double k)
{
this->i=i;
this->j=j;
this->k=k;
}
double getI(){return i;}
double getJ(){return j;}
double getK(){return k;}
double scalar(MathVector &other)
{
return (i*other.getI())+(j*other.getJ())+(k*other.getK());
}
};
int main(int argc, char **argv)
{
MathVector a(1,2,5), b(2,4,1);
cout << a.scalar(b) << endl;
return 0;
}