明天上T考场

忙乱的暑假,没空照看这里
不多说了,向各位汇报一下情况,考完再来打点
bless me
#include<iostream> #include<string> #include<vector>//动态数组 #include<algorithm>//提供sort功能 #include<ctime> #include<map> using namespace std; class Task; vector<Task*> list;//负责存储、管理所有任务对象 // 辅助函数:将时间字符串(HH:MM)转换为分钟数 int stoint(string time); //任务基类 - 抽象类,所有具体任务类型继承自此类 string NowTime(); void delay(int z) { int x,y; for(x=z;x>0;x--) { for(y=0;y<z;y++); //TODO } } class Task { public: // 记录当前系统中任务的总数 // 构造函数,初始化任务基本信息 Task(string n,string d,string s,string e):name(n),day(d),start_time(s),end_time(e){num++;} //虚析构函数,确保先调用真正子类的析构函数,再调用基类析构函数。 virtual ~Task(){num--;}//当删除对象时任务数自动减1。 // 纯虚函数,用于显示任务信息,派生类必须实现 virtual void show()=0;//通过纯虚函数show()实现多态,不同任务类型有不同的显示格式 // 友元类和函数,允许访问Task的私有成员 friend class TaskCounter; friend struct comparebytime; friend bool IsConflict(Task*t1,Task*t2); friend istream& operator>>(istream& cin, Task& t);//运算符重载,通过cin直接写入name、day、start_time和end_time friend void addorremove(); friend void searchimportant(); friend void clearoldtask(); friend int binarysearch(vector<Task*>& list, string day, string time); friend void searchnearest(); friend struct combytime; static int num; protected: string name; // 任务名称 string day; // 任务日期(格式: YYYY-MM-DD) string start_time;// 开始时间(格式: HH:MM) string end_time; // 结束时间(格式: HH:MM) }; // 初始化静态成员变量 int Task::num=0;//静态成员统计任务数量 //课程任务类 子任务类 class CourseTask:public Task{ public: string classroom; // 无参构造函数 CourseTask() : Task("", "", "", ""),classroom("") {} // 带参数的构造函数 CourseTask(string n,string d,string s,string e,string c):Task(n,d,s,e),classroom(c){} // 实现基类的纯虚函数,显示课程任务信息 void show(){ cout << "【课程】" << name <<" 时间:"<<start_time<<'-'<<end_time<< " 教室:" << classroom << endl; } //重写show(),实现差异化的任务信息展示 }; //考试任务类 -子任务类 class ExamTask :public Task{ public: string classroom; // 考场信息 // 无参构造函数 ExamTask():Task("", "", "", ""),classroom("") {} // 带参数的构造函数 ExamTask(string n,string d,string s,string e,string c):Task(n,d,s,e),classroom(c){} // 实现基类的纯虚函数,显示考试任务信息 void show(){ cout << "【考试】" << name <<" 时间:"<<start_time<<'-'<<end_time<< " 考场:" << classroom << endl; } }; // 作业任务类 -子任务类 class HomeworkTask :public Task{ public: string deadline; // 截止时间 // 默认构造函数 HomeworkTask():Task("", "", "", ""),deadline("") {} // 带参数的构造函数 HomeworkTask(string n,string d,string s,string e,string de):Task(n,d,s,e),deadline(de){} // 实现基类的纯虚函数,显示作业任务信息 void show(){ cout << "【课程作业】" << name <<" 时间:"<<start_time<<'-'<<end_time<<" 截止时间:" << deadline << endl; } }; // 比较器结构体 - 用于按开始时间对任务进行排序 struct comparebytime{ bool operator()(Task*&a1,Task*&a2)const{ //bool用于用于存储逻辑值,可用于判断 // 将时间字符串转换为分钟数进行比较 return stoint(a1->start_time) < stoint(a2->start_time);//将时间字符串转换为分钟数并比较,若 a1 的开始时间更早则返回 true } }; //任务的统计和查询类 class TaskCounter { public: TaskCounter() {};//默认构造初始化 ~TaskCounter() {};//析构 // 按日期搜索任务 void searchday(string cinday)//枚举找出日期与cinday相同的任务 { ordertask.clear(); // 清空上一个查询任务列表 for(int i=0;i<int(list.size());i++)//遍历全局任务列表 list(以存储的),筛选出日期等于 cinday 的任务 { if(list[i]->day==cinday) //判断是否等于cinday { ordertask.push_back(list[i]);/*使用 push_back() 将符合条件的任务指针添加到 ordertask ordertask 存储 */ } } //对符合进行排序 orderastime(); } // 按时间排序并显示 void orderastime(){ sort(ordertask.begin(), ordertask.end(), comparebytime());//按照自定义排序规则排序 for(Task*i:ordertask){ i->show(); //多态显示 } } // 静态成员函数,统计指定月的任务数量 static void report(int y,int m) { // 格式化年月字符串 string year=to_string(y); //用于将整数类型的年、月转换为字符串格式 string month=to_string(m); if(m<10) { month="0"+month; } string ym=year+"-"+month; //实现格式:如2025-06 // 初始化各类任务数量 int countc= 0; int counte= 0; int counth= 0; // 验证输入格式 if (ym.size()!=7||ym[4]!='-') { cout << "统计失败!"<<endl; return; } // 遍历所有任务,统计指定年月的任务数量 for (Task*t:list) { if (t->day.substr(0,7)==ym) /*substr(0, 7) 提取任务日期从0开始长度为7的字串*/ { // 使用dynamic_cast判断任务类型 if (dynamic_cast<CourseTask*>(t) != nullptr) ++countc; else if (dynamic_cast<ExamTask*>(t) != nullptr) ++counte; else if (dynamic_cast<HomeworkTask*>(t) != nullptr) ++counth; } } // 输出统计结果 cout << " 月度任务统计 ——"<<endl; cout << " 课程任务 :" << countc<< "条"<<endl; cout << " 考试任务 :" << counte<< "条"<<endl; cout << " 作业任务 :" << counth<< "条"<<endl; cout << "———————————————"<<endl; } vector<Task*>ordertask;//存储任务指针的动态数组,存储筛选后的符合条件的任务子集 }; // 重载输入运算符,用于输入任务基本信息 istream& operator>>(istream& cin, Task& t) { cout << "请输入任务名称(可以包含空格):" << endl; cin.ignore(); // 忽略之前的输入缓冲区 getline(cin, t.name); // 读取整行任务名,允许包含空格 cout << "请输入任务日期(格式:xxxx-xx-xx):" << endl; cin >> t.day; cout << "请输入开始时间(格式:xx:xx):" << endl; cin >> t.start_time; cout << "请输入结束时间(格式:xx:xx):" << endl; cin >> t.end_time; return cin; } struct combytime{ bool operator()(Task*a,Task*b)const{ if(a->day!=b->day) return a->day<b->day; else return stoint(a->start_time) < stoint(b->start_time); } }; // 添加或删除任务的功能函数 void addorremove() { sort(list.begin(),list.end(),combytime()); cout<<"若要添加请按1,删除请按2。"<<endl; int a; cin>>a; cout<<endl; if(a==1) { cout<<"课程请按1 / 考试请按2 / 作业请按3"<<endl; a=0; cin>>a; // 创建相应类型的任务对象 Task* t = nullptr; if (a == 1) t = new CourseTask; else if (a == 2) t = new ExamTask; else if (a == 3) t = new HomeworkTask; if (t) { cin >> *t; // 输入任务基本信息 // 根据任务类型输入额外信息 if (a == 1) { auto ct = dynamic_cast<CourseTask*>(t);//将基类指针 t 转换为派生类 CourseTask* 指针,通过派生类指针访问 classroom 成员变量 cout << "请输入所在教室:" << endl; string c; cin >> c; ct->classroom = c;//将用户输入的教室信息(临时变量 c)赋值给课程任务对象的 classroom 成员变量,通过指针 ct 访问对象成员 } else if (a == 2) { auto et = dynamic_cast<ExamTask*>(t); cout << "请输入考场:" << endl; string c; cin >> c; et->classroom = c; } else if (a == 3) { auto ht = dynamic_cast<HomeworkTask*>(t); cout << "请输入截止时间(格式:xx:xx):" << endl; string d; cin >> d; ht->deadline = d; } // 检查新任务是否与现有任务冲突 for(Task*&l:list){ //遍历全局任务列表 list if(IsConflict(t,l)) //检查新创建的任务 t 是否与现有任务冲突 { cout<<"与原本时间冲突!!!"<<endl; delete t; // 冲突则删除临时创建的任务对象 return; } } // 添加任务到列表 int near =binarysearch(list,t->day,t->start_time); list.insert(list.begin() + near, t); //按时间顺序添加 cout<<"添加成功!"<<endl; } } else if(a==2) { cout<<"请输入你要删除的任务的日期和名称:"<<endl; string a,b; cin>>a>>b; for(int i=0;i<int(list.size());i++) //遍历任务列表 list { if(list[i]->day==a&&list[i]->name==b)//删除所有日期为 a 且名称为 b 的任务 { list.erase(list.begin()+i); //从任务列表 list 中删除索引为 i 的元素 cout<<"删除成功!"<<endl; } } } else cout<<"wrong!"<<endl; } // 全局任务计数类对象 TaskCounter counter; // 按日期查询日程的功能函数 void showschedule() { cout<<"请输入你想要查询日程的日期(按照xxxx-xx-xx 年-月-日的形式):"<<endl; string a; cin>>a; counter.searchday(a);//通过遍历任务列表并比较日期字符串,实现了按日期搜索任务的功能 } // 统计当月任务数量的功能函数 void number() { cout<<"请输入你想要查询任务数量的年份:"; int a; cin>>a; cout<<endl; cout<<"请输入你想要查询任务数量的月份:"; int b; cin>>b; cout<<endl; TaskCounter::report(a,b);//输入年份 a 和月份 b,统计该月份的课程任务、考试任务和作业任务数量,显示统计结果 } // 按关键字搜索任务的功能函数 void searchimportant() { cout<<"请输入你所要查找的关键字:"<<endl; string a; cin>>a; // 遍历所有任务,查找名称中包含关键字的任务 for(Task*t:list) { if(t->name.find(a)!= string::npos)//查看是否存在位置 { t->show();//根据 t 指向的实际对象类型,调用相应的 show() 实现 } } cout<<"搜索结束 ------------"<<endl; } bool isLeapYear(int year) { return (year % 400 == 0) ? true : (year % 100 == 0) ? false : (year % 4 == 0) ? true : false; } void searchnearest() { Task* t = list[0]; t->show(); //cout << "DEBUG t->day = [" << t->day << "], size=" << t->day.size() << endl; cout << "距离本次任务还有:"; string now = NowTime(); // YYYY-MM-DD HH:MM:SS string td = t->day; // YYYY-MM-DD //判断格式是否正确 if (t->start_time.size() < 5) { // 补到至少 "HH:MM" 的长度 if (t->start_time.size() == 4 && t->start_time[1] == ':') { t->start_time = "0" + t->start_time; // H:MM → HH:MM } else if (t->start_time.size() == 4 && t->start_time[2] == ':') { t->start_time.insert(3, "0"); // HH:M → HH:MM } else if (t->start_time.size() == 3) { t->start_time = "0" + t->start_time; // HMM → 0HMM } } if (t->start_time.size() < 5 || t->start_time[2] != ':') { cout << "时间格式不标准,已自动置为 00:00,原值:" << t->start_time << endl; t->start_time = "00:00"; } // ------------------------------------------------------- int ny = stoint(now.substr(0,4));//y year int ty = stoint(td.substr(0,4)); int nm = stoint(now.substr(5,2));//m month int tm = stoint(td.substr(5,2)); int nd = stoint(now.substr(8,2));//d day int td2 = stoint(td.substr(8,2)); int nh = stoint(now.substr(11,2));//h hour int th = stoint(t->start_time.substr(0,2)); int nmin = stoint(now.substr(14,2));//min int tmin = stoint(t->start_time.substr(3,2)); // 先判断年份 if (ny != ty) { cout << (ty - ny) << "年"; } // 计算月份差 int month = tm - nm; int day = td2 - nd; // 若日期不足,向月份借 if (day < 0) { month -= 1; int daysInMonth; switch (nm) { case 2: daysInMonth = isLeapYear(ny) ? 29 : 28; break; case 4: case 6: case 9: case 11: daysInMonth = 30; break; default: daysInMonth = 31; } day += daysInMonth; // 补 日期 } if (month > 0) { cout << month << "月"; } if (day > 0) { cout << day << "天"; } // 若到了同一天,算小时分钟 if (month <= 0 && day <= 0) { int h = th - nh; int m = tmin - nmin; if (m < 0) { m += 60; h -= 1; } cout << h << "小时" << m << "分钟"; } cout << endl; } string NowTime() { time_t now = time(0); string stringtime = ctime(&now); if (stringtime[8] == ' ') stringtime[8] = '0'; //补0:变day为0x或xx两位的形式 static const map<string, string> monthMap = { {"Jan", "01"}, {"Feb", "02"}, {"Mar", "03"}, {"Apr", "04"}, {"May", "05"}, {"Jun", "06"}, {"Jul", "07"}, {"Aug", "08"}, {"Sep", "09"}, {"Oct", "10"}, {"Nov", "11"}, {"Dec", "12"} }; string stringmonth = stringtime.substr(4, 3); size_t pos = stringtime.rfind(' '); string stringyear = stringtime.substr(pos + 1, 4); // 处理 HH:MM string hm = stringtime.substr(11, 5); if (hm[0] == ' ') hm[0] = '0'; // 补0:变 " 9:03" → "09:03" string stringnow = stringyear + "-" + monthMap.at(stringmonth) + "-" + stringtime.substr(8, 2) + " " + hm; return stringnow; } // 辅助函数:将时间字符串(HH:MM)转换为分钟数 int stoint(string time) { string ti1=time.substr(0,2); // 提取小时部分 string ti2=time.substr(3,2); // 提取分钟部分 int hour=stoi(ti1); // 转换为整数 int min=stoi(ti2); // 转换为整数 return 60*hour+min; // 返回总分钟数 } // 判断两个任务是否时间冲突 bool IsConflict(Task*t1,Task*t2) { if(t1->day!=t2->day) return false; // 不同日期的任务不冲突 // 判断时间是否重叠 if(stoint(t1->end_time)<=stoint(t2->start_time)) { return false; } else if(stoint(t1->start_time)>=stoint(t2->end_time)) { return false; } return true; // 否则冲突 } void clearoldtask() { cout << "\n[系统提示] 正在清理已过期任务..." << endl; string now = NowTime(); string today = now.substr(0, 10); int n = 0;//统计清除的条数 for (int j = 0; j < int(list.size()); j++) { Task* i = list[j]; // 当前任务指针 if (i->day < today ) { delete i; // 释放指针指向的数据内存 list.erase(list.begin() + j); // 从list删除这个任务指针 n++; j--; // erase将后面都向前提 } } cout << "[系统提示] 已清理 " << n << " 条过期任务。\n"; if(Task::num==0) cout<<"当前所有任务已被清空"<<endl; } int binarysearch(vector<Task*>& list, string day, string time) { int l = 0, r = list.size() - 1; int t = stoint(time); while (l <= r) { int mid = (l + r) / 2; Task* m = list[mid]; // 日期不同,按日期比较 if (m->day < day) l = mid + 1; else if (m->day > day) r = mid - 1; else { // 日期相同,再比较时间 int mid_time = stoint(m->start_time); if (mid_time == t) return mid; if (mid_time < t) l = mid + 1; else r = mid - 1; } } return l; // 返回应插入位置 } // 系统菜单函数 void menu() { cout << " 智能日程管理系统 " << endl; int a; while (true) { cout << "当前共存任务:" << Task::num << " 条"<<endl;//num没设置为私有成员的原因 cout << "智能日程管理系统菜单" << endl; cout << "1. 添加/删除任务" << endl; cout << "2. 查询日程" << endl; cout << "3. 统计当月任务数量" << endl; cout << "4. 搜素关键词" << endl; cout << "5. 查找最近一次任务以及距离时间"<<endl; cout << "6. 清除过期任务"<<endl; cout << "7. 退出系统" << endl; cout << "请选择操作编号:"; cin >> a; switch (a) { case 1: addorremove(); break; case 2: showschedule(); break; case 3: number(); break; case 4: searchimportant(); break; case 5: searchnearest(); break; case 6: clearoldtask(); break; case 7: cout << "感谢使用,再见!" << endl; return; default: cout << "无效选择,请重新输入" << endl; } delay(100); } } //主函数 int main() { cout<<"当前时间为:"<<NowTime(); // 初始化测试数据 list.push_back(new CourseTask("高等数学", "2025-11-17", "09:00", "10:30", "三教A112"));//使用 new 分配对象 list.push_back(new CourseTask("大学英语", "2026-06-10", "15:45", "18:15", "一教205")); list.push_back(new ExamTask("英语期中考试", "2025-12-11", "10:00", "11:30", "教A102")); list.push_back(new HomeworkTask("课程设计", "2025-06-10", "00:00", "23:59", "三教A102")); list.push_back(new CourseTask("大学物理", "2025-06-06", "08:00", "09:30", "三教A212")); // 显示菜单并处理用户操作 menu(); // 释放内存,避免内存泄漏 for (Task* t : list) { delete t; } list.clear(); //调用 clear() 方法清空任务列表 return 0; }我的查找最近任务会输出错误,帮我分析哪里不对
最新发布
11-18
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值