要求:
Write a computer program that could be used to track users' activities.
Lab Number | Computer Station Numbers |
1 | 1-3 |
2 | 1-4 |
3 | 1-5 |
4 | 1-6 |
? You run four computer labs. Each lab contains computer stations that are numbered as the above table.
? There are two types of users: student and staff. Each user has a unique ID number. The student ID starts with three characters (for example, SWE or DMT), and is followed by three digits (like, 001). The staff ID only contains digits (for example: 2023007).
? Whenever a user logs in, the user’s ID, lab number, the computer station number and login date are transmitted to your system. For example, if user SWE001 logs into station 2 in lab 3 in 01 Dec, 2022, then your system receives (+ SWE001 2 3 1/12/2022) as input data. Similarly, when a user SWE001 logs off in 01 Jan, 2023, then your system receives receives (- SWE001 1/1/ 2023). Please use = for end of input.
? When a user logs in or logs off successfully, then display the status of stations in labs. When a user logs off a station successfully, display student id of the user, and the number of days he/she logged into the station.
? When a user logs off, we calculate the price for PC use. For student, we charge 0 RMB if the number of days is not greater than 14, and 1 RMB per day for the part over 14 days. For staff, we charge 2 RMB per day if the number of days is not greater than 30, and 4 RMB per day for the part over 30 days.
? If a user who is already logged into a computer attempts to log into a second computer, display "invalid login". If a user attempts to log into a computer which is already occupied, display "invalid login". If a user who is not included in the database attempts to log off, display "invalid logoff".
附加要求:
1. 必須是包含以下內容的面向對象程序: ComputerLab 類、基類User 及其派生類 Student和Staff、main 函數。
2. 把 ComputerLab 類作為類 User、 Student、 Staff 的友元,使它直接訪問各類用戶的私有成員。
3. 為 ComputerLab 類重載操作符 + 和 - ,分別實現 Staff 和 Student 的登錄和退出功能:
//請合理設計登錄和退出請求的數據類型
? void operator + (StaInReq &r); //Staff 登錄
? void operator + (StuInReq &r); //Student 登錄
? void operator - (StaOffReq &r); //Staff 退出
? void operator - (StuOffReq &r); //Student 退出
輸入樣例:
+ SWE100 1 1 1/1/2016
+ DMT200 2 6 02/04/2016
+ SWE400 1 1 1/01/2016
+ SWE400 4 3 10/1/2016
+ SWE400 2 1 1/1/2015
+ 2019007 2 3 1/1/2015
- 2019007 1/12/2016
- DMT700 1/12/2016
+ SWE800 1 6 10/10/2013
+ SWE900 5 1 10/10/2014
- SWE700 1/12/2016
=
代碼實現:
頭文件c_user.hpp
#ifndef C_USER_HPP_INCLUDED
#define C_USER_HPP_INCLUDED#pragma once
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class ComputerLab;
class User {
public:User() :id("empty"), year(0), month(0), day(0){}User(const string& id, int y = 0, int m = 0, int d = 0) : id(id), year(y), month(m), day(d) {}const string& getId() const {return id;}private:friend class ComputerLab;int year, month, day;string id;
};class Student : public User {
public:Student(const string& id, int y = 0, int m = 0, int d = 0) : User(id, y, m, d) {}
};class Staff : public User {
public:Staff(const string& id, int y = 0, int m = 0, int d = 0) : User(id, y, m, d) {}
};
struct StaInReq
{Staff* pointer;int labNum;int stationNum;
};
struct StuInReq
{Student* pointer;int labNum;int stationNum;
};
struct StaOffReq
{Staff* pointer;
};
struct StuOffReq
{Student* pointer;
};
class ComputerLab
{
public:ComputerLab();void operator+(StaInReq& r);void operator+(StuInReq& r);void operator-(StaOffReq& r);void operator-(StuOffReq& r);void display()const;
private:void show(const vector<User>& v)const;void show_date(const User& u)const;vector<vector<User>> Rooms;pair<int, int> check(const string& str);int calculate(User& u1, User& u2)const;
};#endif // C_USER_HPP_INCLUDED
源文件computer.cpp實現類內成員函數
#include "c_user.hpp"
int M[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };
ComputerLab::ComputerLab():Rooms(4)
{this->Rooms[0] = vector<User>(3, User());this->Rooms[1] = vector<User>(4, User());this->Rooms[2] = vector<User>(5, User());this->Rooms[3] = vector<User>(6, User());
}
void ComputerLab::show_date(const User& u)const
{cout<<" ";if (u.month < 10)cout << 0;cout << u.month << "/";if (u.day < 10)cout << 0;cout << u.day<<"/";cout<<u.year;return;
}
void ComputerLab::show(const vector<User>& v)const
{for (int i = 0; i < v.size(); i++) {cout << " " << i + 1 << ":" << v[i].id;if (v[i].id != "empty"){show_date(v[i]);}}cout << endl;
}
void ComputerLab::display()const
{for (int i = 0; i < Rooms.size(); i++) {cout << i + 1 << ":";show(Rooms[i]);}
}
pair<int, int> ComputerLab::check(const string& str)
{for (int i = 0; i < 4; i++){for (int j = 0; j < this->Rooms[i].size(); j++){if (Rooms[i][j].id == str)return(make_pair(i, j));}}return make_pair(-1, -1);
}
bool is_leap_year(int m)
{if(m%400==0)return 1;if(m%100==0)return 0;if(m%4==0)return 1;return 0;
}
int ComputerLab::calculate(User& u1, User& u2)const
{int d=0;for(int i=u1.year+1;i<u2.year;i++){d+=365;if(is_leap_year(i))d+=1;}d+=365;if(is_leap_year(u1.year)){d+=1;M[2]=29;}for(int i=1;i<u1.month;i++){d-=M[i];}d-=u1.day;if(!is_leap_year(u2.year))M[2]=28;else M[2]=29;for(int i=1;i<u2.month;i++){d+=M[i];}d+=u2.day;if(u1.year==u2.year){d-=365;if(M[2]==29)d-=1;}return d;
}
void ComputerLab::operator+(StaInReq& r)
{pair<int, int> p = check(r.pointer->id);int x = p.first, y = p.second;if (x != -1){cout << "invalid login" << endl;return;}x = r.labNum, y = r.stationNum;if(x>=4||y>=Rooms[x].size()||Rooms[x][y].id!="empty"){cout << "invalid login" << endl;return;}Rooms[x][y] = *(r.pointer);
}
void ComputerLab::operator+(StuInReq& r)
{pair<int, int> p = check(r.pointer->id);int x = p.first, y = p.second;if (x != -1){cout << "invalid login" << endl;return;}x = r.labNum, y = r.stationNum;if(x>=4||y>=Rooms[x].size()||Rooms[x][y].id!="empty"){cout << "invalid login" << endl;return;}Rooms[x][y] = *(r.pointer);
}
void ComputerLab::operator-(StaOffReq& r)
{pair<int, int> p = check(r.pointer->id);int x = p.first, y = p.second;if (x == -1){cout << "invalid logoff" << endl;return;}int d = calculate(Rooms[x][y], *(r.pointer));cout << (r.pointer)->id << " log off, time: " << d << " days, ";int cost = 0;if (d <= 30){cost = d * 2;}else{cost = 60;d -= 30;cost += d * 4;}cout << "price: " << cost << " RMB" << endl;Rooms[x][y]=User();
}
void ComputerLab::operator-(StuOffReq& r)
{pair<int, int> p = check(r.pointer->id);int x = p.first, y = p.second;if (x == -1){cout << "invalid logoff" << endl;return;}int d = calculate(Rooms[x][y], *(r.pointer));cout << (r.pointer)->id << " log off, time: " << d << " days, ";int cost = 0;if (d > 14){cost = d - 14;}cout << "price: " << cost << " RMB" << endl;Rooms[x][y]=User();
}
主函數調用main.cpp
#include <iostream>
#include <string>
#include <vector>
#include <cstdio>
#include "c_user.hpp"
using namespace std;int main() {ComputerLab lab;char op = '+';while (cin >> op && op != '=') {if (op == '+') {string id;int y, m, d, labnum, station;cin >> id >> labnum >> station;labnum-=1,station-=1;scanf("%d/%d/%d",&d,&m,&y);if (id[0] >= '0' && id[0] <= '9'){Student s(id, y, m, d);StuInReq r;r.pointer = &s, r.labNum = labnum, r.stationNum = station;lab + r;}else{Staff s(id, y, m, d);StaInReq r;r.pointer = &s, r.labNum = labnum, r.stationNum = station;lab + r;}lab.display();}else if (op == '-') {string id;int y, m, d, labnum, station;cin >> id;scanf("%d/%d/%d",&d,&m,&y);if (id[0] >= '0' && id[0] <= '9'){Student s(id, y, m, d);StuOffReq r;r.pointer = &s;lab - r;}else{Staff s(id, y, m, d);StaOffReq r;r.pointer = &s;lab - r;}lab.display();}else {cout << "Wrong input" << endl;}}return 0;
}