18

我正在尝试编写一个带有double_product(vector<double> a, vector<double> b)计算两个向量的标量积的函数的程序。标量积是

$a_{0}b_{0}+a_{1}b_{1}+...+a_{n-1}b_{n-1}$.

这就是我所拥有的。这是一团糟,但我正在努力!

#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;
}
4

5 回答 5

46

除非您需要自己执行此操作(例如,编写它是家庭作业),否则您应该真正使用已经编写好的标准算法来完成您想要的操作:

#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;
}

请注意,虽然begin(a)end(a)是 C++11 中的新功能,std::inner_product但自 C++98 起就可用。如果您使用的是 C++ 98(或 03),那么编写自己的等价物beginend使用数组非常容易:

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;
}

使用这些,先前代码的 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;
}

请注意,the beginand endabove 仅适用于数组,其中beginandend在 C++11(及更高版本)中也适用于定义 a.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(); }
于 2012-06-06T04:44:41.233 回答
12

您可以删除class已定义的。你不需要它。

在您的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;
}

快到了。你不需要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;
}

现在要调用这个函数,你需要在你的 中创建 2 个向量对象,main()用值填充它们,(当然是相同数量的值!)然后调用scalar_product( first_vector_that_you_create, second_vector_object );

于 2012-06-06T04:22:14.030 回答
3

虽然已经向您展示了许多可行的解决方案,但让我提出另一个变体来介绍一些可以帮助您编写更好的代码的概念:

  • class只需要将数据打包在一起
  • 功能应尽快检查其先决条件,这些应记录在案
  • 一个函数应该有后置条件,这些应该记录在案
  • 代码重用是可维护程序的基石

考虑到这一点:

// 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

您可以决定inner_product直接使用该算法,但让我们面对现实吧:

  • 它需要四个参数,而不是两个
  • 它不检查它的参数是否相同大小

所以最好把它包起来。

注意:我曾经const&向编译器指示不要复制向量。

于 2012-06-06T06:40:51.150 回答
1

这是您应该拥有的代码。我看到你在你的代码中使用了类,你在这里并不需要。让我知道问题是否需要您使用课程。

由于您是新手,因此此代码可能会吓到您。因此,我将尝试解释这一点。在代码中查找注释以了解正在执行的操作并询问您是否不理解。

//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;
}

如果您使用的是 IDE,则只需编译并运行即可。如果您在带有 g++ 编译器的基于 Unix 的系统上使用命令行,您将执行以下操作(其中 Scalar.cpp 是包含代码的文件):

g++ Scalar.cpp -o scalar

要运行它,只需键入

./scalar

您应该得到1.99上述程序的输出。

于 2012-06-06T04:38:04.847 回答
0

您似乎想专门为向量创建一个类。我在示例中创建的类是针对 3 维向量量身定制的,但如果需要,您可以将其更改为另一个。该类包含 i、j、k,但也可以基于其他 MathVector 进行标量积。另一个向量通过 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;
}
于 2012-06-06T04:28:25.133 回答