#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
class ProductRating
{
public:
ProductRating(int id): id_(id),up(0),total(0) {}
void add_rating(int stars) { up += stars, total += 5; }
double low_score(double z)const
{
if (!total) return 0;
double n = total;
double p = up/n;
return (p + z*z/(2*n) - z * sqrt((p*(1-p)+z*z/(4*n))/n))/(1+z*z/n);
}
double avg_score()const { return total ? (double)up/total : 0; }
int id()const {return id_;};
private:
int id_;
int up;
int total;
};
bool avg_cmp_rev(const ProductRating& a, const ProductRating& b)
{
return b.avg_score() < a.avg_score();
}
bool low_cmp_rev(const ProductRating& a, const ProductRating& b)
{
return b.low_score(1.96) < a.low_score(1.96);
}
int main()
{
vector<ProductRating> rating_list;
rating_list.push_back(ProductRating(1));
rating_list.push_back(ProductRating(2));
rating_list.push_back(ProductRating(3));
// 3 lần đánh giá 5 sao
rating_list[0].add_rating(5);
rating_list[0].add_rating(5);
rating_list[0].add_rating(5);
// 100 lần đánh giá 5 sao, 2 lần đánh giá 2 sao
for (int i=0; i<100; ++i) rating_list[1].add_rating(5);
rating_list[1].add_rating(2);
rating_list[1].add_rating(2);
// 2 > 1 > 3
cout << "Average score:\n";
for (size_t i=0; i<rating_list.size(); ++i)
cout << "Product " << rating_list[i].id() << ": "
<< rating_list[i].avg_score() << '\n';
cout << "\nLower bound of Wilson score, 95% confidence:\n";
for (size_t i=0; i<rating_list.size(); ++i)
cout << "Product " << rating_list[i].id() << ": "
<< rating_list[i].low_score(1.96) << '\n';
sort(rating_list.begin(), rating_list.end(), avg_cmp_rev);
cout << "\nAfter sorted by average score: ";
for (size_t i=0; i<rating_list.size(); ++i)
cout << rating_list[i].id() << " ";
cout << "\n";
sort(rating_list.begin(), rating_list.end(), low_cmp_rev);
cout << "After sorted by lower bound of Wilson score (95% confidence): ";
for (size_t i=0; i<rating_list.size(); ++i)
cout << rating_list[i].id() << " ";
cout << "\n";
}