Question: A leading shopping website generates logs everyday of customers visiting their website along with the page number that they visited. Each entry contains the customer unique id and the page id, which the customer visited. Given the logs of 3 days, and the customer id, check whether the customer visited exactly on 2 out of 3 days and also check whether he visited more than 3 different pages?
#include <iostream>
#include <hash_map>
#include <list>
#include <set>
#include <bitset>
#include <string>
using namespace std;
using namespace stdext;
const int PAGE_VIEW_COUNT = 3;
const int DAYS_VISIT_COUNT = 2;
class CustomerData
{
public:
bitset<PAGE_VIEW_COUNT> days;
set<int> pages;
CustomerData(bitset<PAGE_VIEW_COUNT> d, set<int> p) : days(d), pages(p)
{
}
CustomerData() : days(string("000")) //Use days.reset, if PAGE_VIEW_COUNT != 3
{
}
};
hash_map<int, CustomerData> entries;
hash_map<int, CustomerData>::const_iterator recordIter;
typedef pair<int, CustomerData> CustomerRecordEntry;
void GenerateCustomerList(const list<pair<int, int>>& cuslist, int logNum);
int main()
{
list<pair<int, int>> log1, log2, log3;
log1.push_back(make_pair(1,1));
log1.push_back(make_pair(2,2));
log1.push_back(make_pair(4,1));
log1.push_back(make_pair(1,3));
log2.push_back(make_pair(2,1));
log2.push_back(make_pair(2,4));
log2.push_back(make_pair(4,2));
log2.push_back(make_pair(1,3));
log2.push_back(make_pair(1,5));
log3.push_back(make_pair(3,2));
log3.push_back(make_pair(4,4));
log3.push_back(make_pair(5,2));
log3.push_back(make_pair(5,5));
GenerateCustomerList(log1, 1);
GenerateCustomerList(log2, 2);
GenerateCustomerList(log3, 3);
int cid = 0;
cout << "Enter customer ID: " ;
cin >> cid;
recordIter = entries.find(cid);
if(recordIter != entries.end())
{
CustomerData data = (CustomerData)recordIter->second;
if(data.days.count() == DAYS_VISIT_COUNT && data.pages.size() == PAGE_VIEW_COUNT)
{
cout << "Customer visited on exactly 2 days and have 3 or more distinct page views."
<< endl;
}
else
{
cout <<
"Customer didn't visited on exactly 2 days or have 3 or more distinct page views."
<< endl;
}
}
else
cerr << "Customer ID not found in logs." << endl;
cout << endl;
return 0;
}
void GenerateCustomerList(const list<pair<int, int>>& cuslist, int logNum)
{
list<pair<int, int>>::const_iterator iter;
for(iter = cuslist.begin(); iter != cuslist.end(); iter++)
{
recordIter = entries.find(iter->first);
if(recordIter != entries.end())
{
CustomerData data = (CustomerData)recordIter->second;
data.days.set((logNum-1), true);
//Space optimization
//Check if already have 3 distinct page view, no need to add more
if(data.pages.size() < PAGE_VIEW_COUNT)
data.pages.insert(iter->second);
entries[recordIter->first] = data;
}
else
{
bitset<PAGE_VIEW_COUNT> days(string("000"));
days.set((logNum-1), true);
set<int> pages;
pages.insert(iter->second);
CustomerData data(days, pages);
entries.insert(CustomerRecordEntry(iter->first, data));
}
}
}