Project #1 - Sorted Date List
- Read a sequence of dates from file input.
-
Permissible formats for dates include
dd/mm/yyyy e.g. 01/01/1970 d MMM yyyy e.g. 1 JAN 1970 MMM d, 1970 e.g. JAN 1, 1970 MMMM d, yyyy e.g. January 1, 1970.
- Sort and output the dates such that the later dates come first.
- Use functions from the STL's: `<string>`, `<algorithm>`, `<regex>`, `<iterator>`, `<array>`.
- Create your customised MyDate class.
Solution:
#include <iostream>
#include <string>
#include <algorithm>
#include <regex>
#include <iterator>
#include <array>
#include <fstream>
#include <iomanip>
#define N 25
class Date
{
private:
int day;
int month;
int year;
std::array<std::string, 12> _months = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
public:
Date()
{
day = 9999;
month = 9999;
year = 9999;
}
Date(std::string str_date)
{
day = 1;
month = 1;
year = 1970;
_date_parser(str_date);
}
~Date() {}
bool is_valid()
{
if (day > 31 || day < 1)
return false;
if (month > 12 || month < 1)
return false;
if (year > 9999 || year < 1000)
return false;
return true;
}
void _date_parser(std::string str_date)
{
std::string _months_abbr_pattern = "", _months_pattern = "";
for (size_t i = 0; i < _months.size(); i++)
{
_months_abbr_pattern += _months[i].substr(0, 3);
if (_months.size() - 1 != i)
{
_months_abbr_pattern += "|";
}
}
for (size_t i = 0; i < _months.size(); i++)
{
_months_pattern += _months[i];
if (_months.size() - 1 != i)
{
_months_pattern += "|";
}
}
std::array<std::regex, 10> patterns({
std::regex("([0-2][1-9]|3[0-1])\\s*[, /\\-]\\s*(0[1-9]|1[0-2])\\s*[, /\\-]\\s*([1-5]\\d{3})"),
std::regex("([1-9]|[1-2][1-9]|3[0-1])\\s*[, /\\-]\\s*(" + _months_abbr_pattern + ")\\s*[, /\\-]\\s*([1-5]\\d{3})", std::regex::icase),
std::regex("(" + _months_abbr_pattern + ")\\s*[, /\\-]\\s*([1-9]|[1-2][1-9]|3[0-1])\\s*[, /\\-]\\s*([1-5]\\d{3})", std::regex::icase),
std::regex("(" + _months_pattern + ")\\s*[, /\\-]\\s*([1-9]|[1-2][1-9]|3[0-1])\\s*[, /\\-]\\s*([1-5]\\d{3})", std::regex::icase),
});
std::smatch match;
bool check = false;
for (size_t i = 0; i < patterns.size(); i++)
{
if (std::regex_match(str_date, patterns[i]))
{
std::regex_search(str_date, match, patterns[i]);
switch (i)
{
case 0:
day = std::stoi(match[1].str());
month = std::stoi(match[2].str());
year = std::stoi(match[3]);
break;
case 1:
day = std::stoi(match[1].str());
month = _months.size();
for (size_t i = 0; i < _months.size(); i++)
{
if (_months[i].substr(0, 3) == match[2].str())
{
month = i + 1;
break;
}
}
year = std::stoi(match[3]);
break;
case 2:
day = std::stoi(match[2].str());
month = _months.size();
for (size_t i = 0; i < _months.size(); i++)
{
if (_months[i].substr(0, 3) == match[1].str())
{
month = i + 1;
break;
}
}
year = std::stoi(match[3]);
break;
case 3:
day = std::stoi(match[2].str());
month = _months.size();
for (size_t i = 0; i < _months.size(); i++)
{
if (_months[i] == match[1].str())
{
month = i + 1;
break;
}
}
year = std::stoi(match[3]);
break;
}
check = true;
break;
}
}
if (!check)
std::cout << "Invalid Format" << std::endl;
}
bool operator>(Date d)
{
if (year > d.year)
return true;
else if (year == d.year)
{
if (month > d.month)
return true;
else if (month == d.month)
{
if (day > d.day)
return true;
else
return false;
}
else
return false;
}
return false;
}
bool operator<(Date d)
{
if (year < d.year)
return true;
else if (year == d.year)
{
if (month < d.month)
return true;
else if (month == d.month)
{
if (day < d.day)
return true;
else
return false;
}
else
return false;
}
return false;
}
std::string _str()
{
std::string str_date = "";
str_date += std::to_string(day) + " ";
str_date += _months[month - 1] + " ";
str_date += std::to_string(year);
return str_date;
}
friend std::ostream &operator<<(std::ostream &os, Date &date)
{
os << date._str();
return os;
}
};
std::array<Date, N> get_dates(std::string filename)
{
std::ifstream infile;
std::string str_date;
std::array<Date, N> date_array;
std::cout << "Get Dates from " << filename << " ... " << std::endl;
int i = 0;
infile.open(filename);
while (std::getline(infile, str_date))
{
if (str_date != "")
date_array[i++] = Date(str_date);
}
infile.close();
return date_array;
}
int main(int argc, char const *argv[])
{
std::array<Date, N> dates = get_dates("date_list.txt");
std::cout << "Sorting Dates ... " << std::endl;
std::sort(dates.begin(), dates.end());
std::array<Date, N>::iterator it;
for (it = dates.begin(); it != dates.end(); it++)
{
if (it->is_valid())
std::cout << *it << std::endl;
}
return 0;
}
Input (date_list.txt):
30/01/3055
30-02-4849
30 01, 3459
16/11/5509
30-06/1571
13-Aug-1768
30/ Apr/1002
2 May 2668
29 JAN, 5802
31 Jul 2224
Jan 7 3106
Apr 31 1632
Mar 6 ,3214
Feb 19, 5063
Sep 6-3652
April 30, 5889
January 13 ,4035
May 21 2671
June 30, 4785
JANUARY 4 2324
Output:
Get Dates from date_list.txt ...
Sorting Dates ...
30 April 1002
30 June 1571
31 April 1632
13 August 1768
31 July 2224
4 December 2324
2 May 2668
21 May 2671
30 January 3055
7 January 3106
6 March 3214
30 January 3459
6 September 3652
13 January 4035
30 June 4785
30 February 4849
19 February 5063
16 November 5509
29 December 5802
30 April 5889
0 comments:
Post a Comment