An idea for data cluster


Lets say I want to create a program to store x/y/z's daily expenditure on a daily basis. The idea that I had in mind was something like the structure below.

(User).(Date).(Typeofexpenditure)

I wanted the data cluster to be in a structure, where the the first column contains the user name. The second column stores the dates and eventually the final column stores the type of expenditure like say groceries/medical or stationery.

For example, if I wanted to retrieve expenditure data for Jerry's medical expenditure on the 28th of May 1995.

A query like this below,

Jerry.28051995.medical =

will give me the exact data i'm looking for. And if I want Jenny's complete expenditure for the 24th of October 2014.

A query like this,

Jenny.24102014


would give me all the expenditure information regarding Jenny on that date.


To structure the data cluster itself. I thought I could use the List template (STL). However with lists, I believe I won't get the structure I'm looking for. Could anyone educate on what my best option would be to design a structure like stated above ? Thank you.




You'd be looking at some form of hashtables aka unordered map (unique Key only) or unordered multi-map (non-unique Key possible) in C++. Below outlined a suggestion for an unordered multi-map. Note I've also included the expenditure amount in addition to the type of expenditure:

1. define the Key, here struct Person:
2. next define the hash function for Person by either:
(a) specialization for template hash<Person>, or
(b) define the hash function as a separate struct;
3. define the Value, here struct Expenditure

Possible alternatives, extensions, next steps etc:
1. overloading extraction operators for Person and Expenditure types to read data from file
2. using lambdas for the hash function
3. using the container methods or std::algorithm's to look up the kind of data you mentioned such as search by date, search by date & expenditure type etc

Sample Program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <string>
#include <unordered_map>

using namespace std;
struct Person
{
	string m_fname;
	string m_lname;
	Person (string fname, string lname) : m_fname (fname), m_lname (lname) {}
	bool operator == (const Person& rhs) const
	{
		return (m_fname == rhs.m_fname && m_lname == rhs.m_lname);
	}
};
ostream& operator << (ostream& os, const Person& p)
{
    os<<"First name: "<<p.m_fname<<", Last name: "<<p.m_lname<<"\n";
    return os;
}
namespace std {
    template <> //in this case legal to specialize template inside std namespace
    struct hash<Person>
    {
        size_t operator()(const Person& p) const
        {
        // Compute individual hash values for m_fname, m_lname and combine them using XOR and bit shifting:
        return ((hash<string>()(p.m_fname) ^ (hash<string>()(p.m_lname) << 1)) >> 1);
        }
    };
}
/*struct PersonHasher //alternatively define hash function as a separate struct and add it to the template argument list for the map;
{
    size_t operator()(const Person& p) const
    {
        return ((hash<string>()(p.m_fname)
             ^ (hash<string>()(p.m_lname) << 1)) >> 1);
    };
};*/
struct Expenditure
{
	string m_date;
	string m_item;
	double m_amount;
	Expenditure (string date, string item, double amount) : m_date (date), m_item (item), m_amount (amount) {}
};
ostream& operator << (ostream& os, const Expenditure& e)
{
    os<<"Date: "<<e.m_date<<" - Item: "<<e.m_item<<", Amount: "<<e.m_amount<<"\n";
    return os;
}
int main()
{
    unordered_map <Person, Expenditure> persExp =
	{
		{Person("John", "Smith"), Expenditure("12/01/16", "Books", 55)},
		{Person("Jane", "Doe"), Expenditure("12/02/16", "Travel", 6500)},
	};
	//below using hash function as separate class
	/*unordered_map <Person, Expenditure, PersonHasher> persExp =
	{
		{Person("John", "Smith"), Expenditure("12/01/16", "Books", 55)},
		{Person("Jane", "Doe"), Expenditure("12/02/16", "Travel", 6500)},
	};*/
	for(auto& elem : persExp)
    {
        cout<<elem.first;
        cout<<elem.second;
    }
}
Output
1
2
3
4
5
6
7
First name: Jane, Last name: Doe
Date: 12/02/16 - Item: Travel, Amount: 6500
First name: John, Last name: Smith
Date: 12/01/16 - Item: Books, Amount: 55

Process returned 0 (0x0)   execution time : 0.031 s
Press any key to continue.

Topic archived. No new replies allowed.