简体   繁体   中英

Creating calendar application in C++ efficiency structure

I'm creating a calendar app in Qt/C++ and I'm deciding how to make the structures.

What I do so far: create sorted vector of appointments (sorted on ascending begin date).

I'm wondering if it can improve the performance if I add a std::map with 52 places (1 for every week) and in each spot a vector of the pointers to appointments during that week. Getting the appointments of eg January would happen in constant time (sort of - taking all the pointers of the first 4 weeks). Disadvantages: every time the user edits/removes/creates an appointment this table has to be reconstructed.

I can also just use the vector and search for the first appointment that starts in January and then look for the last one in January. This would then happen in linear time (N).

I'm guessing that when a user quickly clicks through all the months it's more efficient to have a map-table that can quickly fill the appointments for each month he clicks through, than iterating through the vector from start to end.

Maybe I could keep iterators for each month from my vector?

Any advice? - also excuse me if I placed this in the wrong stack.

If you're not going to use a database, you can try using one big std::map<time_t, Appointment> (instead of time_t , you can also use some other time type that can be easily compared). std::map will keep your appointments sorted as they are inserted. Insertion/lookup/erasing only takes logarithmic time.

When you need to list appointments within a range (say, in January 2012), use std::map::equal_range and supply a comparison functor that looks only at the month (or week, or day). Note that std::map::equal_range is also of logarithmic complexity. Once you have a pair of iterators to the equal range, traversing is constant time for each result.

If there can be duplicate appointments that have the same start time, you'll need to use a std::multimap instead.


As a general "best practice" guideline, you should strive to store your date/times in a compact numeric format (like time_t ), and only convert for input/output purposes. It's the same rationale as storing/computing numeric values as int, float, etc, and only formatting them as a string for input/output purposes. If you want to use a convenient date/time wrapper class (with easy access to days, hours, minutes, etc), then check out the Boost.DateTime library or C++11's std::chrono . Those date/time wrappers should already define operator< , so they can be directly used as the key type in std::map .

You can try using balanced binary-search-trees with keys (Year,Month,Day) and with values as list/vectors of appointments. It should give you O(logn) complexity in accessing days. AFAIR std::map and std::set (and of course std::multiset ) are implemented as RB (or AVL) balanced binary trees. You should be cautious, though - these structures have a much bigger constant of efficiency, so you have to benchmark your app.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM