Вопрос по c++ – Вычисление скалярного произведения двух векторов в C ++

13

Я пытаюсь написать программу с функцией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;
}
Что такое "двойной"? jakebird451
Есть ли на самом деле вопрос здесь? Michael Anderson
Вы пытаетесь построить класс для скалярного произведения? Разве это не должна быть функция или метод пользовательского математического векторного класса? Ваш конструктор не должен возвращать двойное число. jakebird451
Твой вопрос не очень понятен. Мы поняли, что это твоя домашняя работа. Но какой вопрос вы пытаетесь решить и добавить немного подробностей о том, с какой проблемой вы сталкиваетесь? Ankit
@ jakebird451 Я имел в виду & quot; двойной & quot; извиняюсь. HowardRoark

Ваш Ответ

5   ответов
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, просто скомпилируйте и запустите. Если вы используете командную строку в Unix-системе с компилятором g ++, это то, что вы будете делать (где Scalar.cpp - файл, содержащий код):

g++ Scalar.cpp -o scalar

Для запуска просто наберите

./scalar

Вы должны получить1.99 как вывод вышеуказанной программы.

0

вы хотите создать класс специально для векторов. Класс, который я создал в своем примере, адаптирован к 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;
}
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;
}

Сейчасcall эта функция, вам нужно создать 2 векторных объекта в вашемmain(), заполните их значениями (одинаковое количество значений, конечно!) и затем вызовитеscalar_product( first_vector_that_you_create, second_vector_object );

Error: User Rate Limit Exceedednumeric_limits<double>::quiet_NaN();Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededneverError: User Rate Limit Exceededintroduce NaNError: User Rate Limit ExceededwhereError: User Rate Limit ExceededneverError: User Rate Limit Exceeded
3

которые работают, позвольте мне привести еще один вариант, чтобы представить несколько концепций, которые должны помочь вам написать лучший код:

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

С этим в мыслях:

// 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 алгоритм, но давайте посмотрим правде в глаза:

it requires four arguments, not two it does not check for its arguments being of the same size

так что лучше обернуть его.

Note: I used const& to indicate to the compiler not to copy the vectors.

40

писать это как домашнее задание), вам действительно следует использовать стандартный алгоритм, который уже написан, чтобы делать именно то, что вы хотите:

#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), довольно легко написать собственный эквивалент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;
}

Используя их, 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;
}

Обратите внимание, что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(); }

Похожие вопросы