我看完题的大致思路是:
->首先读取文件,对读文件的没一行(一个车辆信息)进行解析,每一行的信息是一个车辆,所以我们要定义车辆信息的结构体,把所有的车辆信息保存在list中。
->对于每一行的信息进行解读,简单实现字符串的解析。(这里也可以采用boost库中的split)
->其次,我们读完文件信息,我们要对容器中的信息拿出,并进行一个个判断,然后放入合适的位置,方便输出结果。
->判断车辆的顺序 :是否报废–是否公里保修–是否定期保养(满足其中第一个满足条件的,便不再继续)
->输出车辆的信息需要对车辆的类型以及车牌进行输出,所以对车辆进行判断后放入map中。map中的k表示车辆的种类,v表示存放相同类型以及满足条件的车牌。最终就是将存放的结果按照顺序一一输出。
CAr_check.h
#pragma once
#include<iostream>
#include<list>
#include<vector>
#include<map>
#include<assert.h>
#include<string>
#include<fstream>
using namespace std;
class Time
{
public:
Time(int year = 1900, int month = 01, int day = 01)
:_year(year)
, _month(month)
, _day(day)
{}
bool IsInvalid() //检测日期是否为有效日期
{
if (_year >= 1900 && _month > 0 && _month<13
&& _day>0 && _day <= GetMonthDays(_year, _month))
{
return true;
}
return false;
}
int GetMonthDays(int year, int month)
{
static int _monthDates[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
return _monthDates[month];
}
int operator-(const Time& t) //两个日期类相减相差天数
{
Time tmp(*this);
int a = 0;
if (_year >= t._year)
{
if (t._month == tmp._month && t._year == tmp._year)
return tmp._day - t._day;
tmp._month--;
while (!((tmp._year == t._year) && (tmp._month == t._month)))
{
a += GetMonthDays(tmp._year, tmp._month);
tmp._month--;
if (tmp._month == 0)
{
tmp._month = 12;
tmp._year--;
}
}
return a + tmp._day + (GetMonthDays(t._year, t._month) - t._day);
}
else
{
tmp = t;
tmp._month--;
while (!((tmp._year == _year) && (tmp._month == _month)))
{
a += GetMonthDays(tmp._year, tmp._month);
tmp._month--;
if (tmp._month == 0)
{
tmp._month = 12;
tmp._year--;
}
}
return -(a + tmp._day + (GetMonthDays(_year, _month) - _day));
}
}
Time operator+(const int day) //日期类加一个整型天数
{
if (day < 0)
{
return *this - (-day);
}
Time tmp(*this);
tmp._day += day;
while (tmp.IsInvalid() == false)
{
tmp._day -= GetMonthDays(tmp._year, tmp._month);
if (tmp._month == 12)
{
tmp._year++;
tmp._month = 1;
}
else
{
tmp._month++;
}
}
return tmp;
}
int _year; //年
int _month; //月
int _day; //日
};
struct Car_information
{
string Number; //车牌号
Time Date; //购买日期
string Type; //品牌名称
int Km; //运行时间
char Repair; //有无大修
};
class Test
{
public:
void Push(const Car_information& c)
{
All.push_back(c);
}
void Reminder()
{
it = All.begin();
while (it != All.end()) //对读入的数据进行筛选
{
Check_repair(it);
it++;
}
Show();
}
void Check_repair(list<Car_information>::iterator& it)
{
vector<string> v1;
int cmp;
int yearcmp = checktime._year - it->Date._year;
if (yearcmp == 0)
cmp = checktime._month - it->Date._month;
else if (checktime._year - it->Date._year == 1)
cmp = (checktime._year - it->Date._year) * 12 - it->Date._month - (12 - checktime._month);
if (checktime._year - it->Date._year > 1)
cmp = (yearcmp)* 12 + checktime._month - it->Date._month;
if (((it->Repair == 'T') && ((cmp >= (36 - 1) || //首先判断是否报废
((it->Date + 1094)._year == checktime._year
&& ((it->Date + 1094)._month - 1) == checktime._month))))
|| ((it->Repair == 'F') && ((cmp >= (72 - 1) ||
((it->Date + 2189)._year == checktime._year
&& ((it->Date + 2189)._month - 1) == checktime._month)))))
{
if ((it->Repair == 'T') && (checktime - it->Date)<1094)
Check_frist_insert(WOFF, v1);
if ((it->Repair == 'F') && (checktime - it->Date)<2189)
Check_frist_insert(WOFF, v1);
return;
}
else if (((it->Km % 10000) == 0) || (it->Km % 10000 >= 9500)) //然后对公里保养进行判断
{
Check_frist_insert(DRM, v1);
return;
}
else //最终对定期保养进行判断
{
if (it->Repair == 'T')
{
if (((checktime._month - it->Date._month) % 3 >= 2)
|| (((checktime._year - it->Date._year)>0)
&& (checktime._month - it->Date._month <= 0)
&& ((checktime._month - it->Date._month + 12) % 3) >= 2))
{
Check_frist_insert(TRM, v1);
return;
}
}
if (it->Repair == 'F' && ((checktime._year - it->Date._year) < 3))
{
if ((((checktime._year - it->Date._year)>0)
&& (((checktime._month - it->Date._month + 12) % 12) >= 11))
|| (((checktime._year - it->Date._year) == 0)
&& (((checktime._month - it->Date._month) == 0))))
{
Check_frist_insert(TRM, v1);
return;
}
}
if (it->Repair == 'F' && ((checktime._year - it->Date._year) >= 3))
{
if (((checktime._month - it->Date._month>0)
&& ((checktime._month - it->Date._month) % 6 >= 5)
|| (checktime._month - it->Date._month) % 6 == 0)
|| (((checktime._month - it->Date._month + 12) % 6) >= 5))
Check_frist_insert(TRM, v1);
return;
}
}
}
void Check_frist_insert(map<string, vector<string>>& m, vector<string>& v) //满足条件放入对应的map中
{
if (m.find(it->Type) == m.end()) //如果先前没有相同类型的插入,将其插入map
{
v.push_back(it->Number);
m.insert(pair<string, vector<string>>(it->Type, v));
}
else //如果已经有同型号的车,则插入对应类型的vector中
{
vector<string>& vec = m[it->Type];
vec.push_back(it->Number);
}
}
void Show() //对3种车辆进行打印
{
cout << "Reminder" << endl;
cout << "==================" << endl << endl;
cout << "* Time - related maintenance coming soon..." << endl;
TRM_it = TRM.begin();
vector<string>::iterator Car_num;
while (TRM_it != TRM.end())
{
cout << TRM_it->first << ": " << TRM_it->second.size() << " (";
Car_num = TRM_it->second.begin();
while (Car_num != TRM_it->second.end())
{
cout << *Car_num;
if (++Car_num != TRM_it->second.end())
cout << ",";
else
cout << ")";
}
cout << endl;
TRM_it++;
}
cout << endl;
cout << "* Distance-related maintenance coming soon..." << endl;
DRM_it = DRM.begin();
while (DRM_it != DRM.end())
{
cout << DRM_it->first << ": " << DRM_it->second.size() << " (";
Car_num = DRM_it->second.begin();
while (Car_num != DRM_it->second.end())
{
cout << *Car_num;
if (++Car_num != DRM_it->second.end())
cout << ",";
else
cout << ")";
}
cout << endl;
DRM_it++;
}
cout << endl;
cout << "* Write-off coming soon..." << endl;
WOFF_it = WOFF.begin();
while (WOFF_it != WOFF.end())
{
cout << WOFF_it->first << ": " << WOFF_it->second.size() << " (";
Car_num = WOFF_it->second.begin();
while (Car_num != WOFF_it->second.end())
{
cout << *Car_num;
if (++Car_num != WOFF_it->second.end())
cout << ",";
else
cout << ")";
}
cout << endl;
WOFF_it++;
}
}
private:
list<Car_information> All; //存放文件所有车辆的信息
list<Car_information>::iterator it;
map<string, vector<string>> TRM; //定期保养车辆
map<string, vector<string>>::iterator TRM_it;
map<string, vector<string>> DRM; //公里保养车辆
map<string, vector<string>>::iterator DRM_it;
map<string, vector<string>> WOFF; //报废车辆
map<string, vector<string>>::iterator WOFF_it;
public:
Time checktime; //检验时间
};
list<string> split(const string &s, const string &seperator) //对字符串的解析
{
list<string> result;
typedef string::size_type string_size;
string_size i = 0;
while (i != s.size())
{
int flag = 0; //找到字符串中首个不等于分隔符的字母;
while (i != s.size() && flag == 0){
flag = 1;
for (string_size x = 0; x < seperator.size(); ++x)
if (s[i] == seperator[x]){
++i;
flag = 0;
break;
}
}
flag = 0; //找到又一个分隔符,将两个分隔符之间的字符串取出;
string_size j = i;
while (j != s.size() && flag == 0)
{
for (string_size x = 0; x < seperator.size(); ++x)
if (s[j] == seperator[x]){
flag = 1;
break;
}
if (flag == 0)
++j;
}
if (i != j){
result.push_back(s.substr(i, j - i));
i = j;
}
}
return result;
}
void open_screen()
{
Test t;
string s;
ifstream infile("test.txt"); //创建文件对象
assert(infile.is_open());
getline(infile, s); //对第一行读取
list<string> first_line = split(s, ":"); //进行筛选
list<string>::iterator sfirst = first_line.begin();
sfirst++;
string datef = *sfirst;
list<string> fd = split(datef, "/");
list<string>::iterator first_it = fd.begin();
t.checktime._year = atoi((*first_it).c_str());
first_it++;
t.checktime._month = atoi((*first_it).c_str());
first_it++;
t.checktime._day = atoi((*first_it).c_str());
while (!infile.eof()) //读取文件结尾时结束
{
getline(infile, s); //往下继续读取数据
list<string> v1 = split(s, "|");
list<string>::iterator sit = v1.begin();
Car_information c;
c.Number = *sit;
sit++;
string date = *sit;
list<string> vd = split(date, "/");
list<string>::iterator sd = vd.begin();
c.Date._year = atoi((*sd).c_str());
sd++;
c.Date._month = atoi((*sd).c_str());
sd++;
c.Date._day = atoi((*sd).c_str());
sit++;
c.Type = *sit;
sit++;
c.Km = atoi((*sit).c_str());
sit++;
c.Repair = (*sit)[0];
t.Push(c);
}
t.Reminder();
infile.close();
}
homework.cpp
#include"Car_check.h"
int main()
{
open_screen();
return 0;
}