Ποστάρω μια λύση σε c++ για το
Cosine simmilarities που -αν ο κώδικας μου βγάζει νόημα- μπορεί να φανεί χρήσιμη σε κάποιον. Την έχω δοκιμάσει στα τρία examples που έχει στο site και φαίνεται να δουλεύει. Για λόγους απλότητας δεν παίρνει την είσοδο σαν argument, αλλά τη διαβάζει από την κονσόλα (stdin).
Η συνάρτηση cin_to_array αναλαμβάνει να «αποκωδικοποιήσει» την είσοδο, αποθηκεύοντας τα δύο διανύσματα σε δύο std::vectors, τα A και Β - θα μπορούσε να γίνει και με δύο arrays. Τσεκάρει ταυτόχρονα για τυχόν σφάλματα και αν εντοπίσει κάποιο γυρνάει την τιμή 13 (ERROR).
Η συνέχεια είνα εύκολη με τη χρήση της έτοιμης συνάρτησης inner_product που βρίσκεται στη βιβλιοθήκη numeric και μας δίνει το εσωτερικό γινόμενο των A, B. Με χρήση της ίδας συνάρτησης υπολογίζεται και το μέτρο τους σύμφωνα με τον τύπο
a(εσωτερικο)
a = |
a|^2
Στο τέλος υπολογίζεται και τυπώνεται η γωνία θ.
// bugos 14/10/13, Cosine Similarities http://www.ieee.org/membership_services/membership/students/awards/xtremesamples.html
#include <stdio.h> // printf
#include <math.h> // acos
#include <iostream> //cin, cout
#include <numeric> //inner_product
#include <vector>
using namespace std;
//Inputs a list of integers in the form [6,5,5,...] and stores them in v
#define ERROR 13
int cin_to_array(vector<int> &v)
{
//Ignore '[' or ' [', return error if not found
cin.ignore(2, '[');
if (!cin.good()) return ERROR;
int n;
while (cin >> n) //while there is an int retrieve it and ignore the ',' afterwards
{
v.push_back(n);
if (cin.peek() == ',')
cin.ignore();
}
if (v.empty()) return ERROR; // if no ints read return error
//ignore ']' that comes after no more ints, return error if not found
cin.clear(); //clear the error that stopped the loop
cin.ignore(1, ']');
if (!cin.good()) return ERROR;
}
int main(int argc, char *argv[])
{
//input
vector<int> A,B;
if ( cin_to_array(A) == ERROR ||
cin_to_array(B) == ERROR ||
A.size() != B.size() ) {
cout << "Error";
return 0;
}
//calculations
double AB, magnA, magnB, theta;
AB = inner_product(A.begin(), A.end(), B.begin(), 0); // A dot B
magnA = sqrt( inner_product(A.begin(), A.end(), A.begin(), 0) ); // we use |A|^2 = A(dot)A, since we can compute A(dot)A
magnB = sqrt( inner_product(B.begin(), B.end(), B.begin(), 0) ); // same with b
theta = acos( AB / (magnA * magnB) );
//output
printf("%.4f", theta);
//cout << '\n' << setprecision(4) << fixed << theta; //#include <iomanip>
}
Οποιοδήποτε σχόλιο για τον κώδικα ή τον τρόπο σκέψης είναι παραπάνω από ευπρόσδεκτο.