2012-06-06 2 views
7

Я пытаюсь написать программу с функцией double_product(vector<double> a, vector<double> b), которая вычисляет скалярное произведение двух векторов. Скалярное произведение:Вычисление скалярного произведения двух векторов в C++

$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; 
} 
+1

На самом деле вопрос здесь? –

+0

Что такое "bouble"? – jakebird451

+0

Вопрос не очень ясен. Мы понимаем, что это ваша домашняя работа. Но какой вопрос вы пытаетесь решить и добавить немного подробностей о том, с какими проблемами вы столкнулись? – Ankit

ответ

10

Вы можете удалить 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);

+1

Обработка ошибок в этой реализации опасна. -1 не соответствует неопределенным в скалярном произведении. Иногда это может показаться очень хорошим. Существует предупреждение, напечатанное там, но это можно легко игнорировать, особенно для больших программ, где текст может быть скрытым, или если имеется много напечатанного текста. Попробуйте вместо этого * numeric_limits :: quiet_NaN(); * Какой возврат nan. – patrik

+1

Я бы всегда, когда-либо, добровольно [вводил NaN] (http://stackoverflow.com/a/18283170/111307) в свою программу. NaN является токсичным (NaN * число = NaN, NaN + число = NaN), поэтому он распространяется по всей вашей программе, и выяснение того, где был произведен NaN, на самом деле тяжело (если только ваш отладчик не может немедленно разорваться при производстве NaN). Тем не менее, таинственный -1 может нелегко отслеживать как таинственный 0, поэтому я мог бы изменить его на -1. Если вы не будете регулярно отслеживать вывод текста своей программы, я, вероятно, также добавлю ASSERT в это условие. Но __never__ возвращает NaN. – bobobobo

+0

Отслеживание NaN, которое не было результатом операции деления, я ожидал бы, что вы будете вдвойне сложны. – bobobobo

0

You похоже, хотят сделать класс специально для векторов. Класс, который я сделал в моем примере, адаптирован к 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; 
} 
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 основе с компилятором г ++, это то, что вы будете делать (где Scalar.cpp это файл, содержащий код):

g++ Scalar.cpp -o scalar 

Чтобы запустить его просто наберите

./scalar 

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

+0

Спасибо, я ценю вашу помощь: D – HowardRoark

33

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

#include <iostream> 
#include <numeric> 

int main() { 
    double a[] = {1, 2, 3}; 
    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.

+8

+1 для обучения меня о 'inner_product'. –

3

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

  • class только необходимый для упаковки данных вместе
  • функция должна проверить свои предпосылки как можно скорее, те должны быть документально
  • функцию, должна иметь постусловий, те должны быть документально
  • повторное использование кода является краеугольным камнем maintenable программ

Имея это в виду:

// 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&, чтобы указать компилятору, чтобы не копировать векторы.

+0

Спасибо! Я очень ценю это. – HowardRoark

Смежные вопросы