工资设计优化
用 STL中的容器和算法对原来的工资设计 程序进行改写,原程序中对于数据的保存和处理主要是在 SalarySys 类中进行,所以对于程序的改写也主要就是对于 SalarySys 类的改写。针对原程序中存在的问题:
- 首先,用可以动态改变大小的 vector 容器来保存那些会动态增减的员工数据。这样,容器的大小会随着数据的增减而动态变化, 不至于浪费内存资源,也不会出现空间不够的情况。
- 同时, vector 容器提供了丰富的成员函数,让我们对数据的访问既便捷又安全。
- 其次,用 STL 中的 find_if()算法以及 max_element()算法代替了原来使用 for 循环遍历数组进行的查找,这样我们只需要关心这些算法中最核心的业务逻辑,而无需关心 for 循环如何访问数组。
完整代码如下:
#include <ctime>
#include <string>
#include <iostream>
#include <fstream>
#include <climits>
#include <vector>
#include <algorithm>
using namespace std;
enum EmpLevel
{
enumOfficer = 1,
enumStaff = 2
};
class Employee
{
public:
Employee(string strName, int nYear):m_strName(strName),m_nYear(nYear)
{}
public:
string GetName() const
{
return m_strName;
}
int GetYear() const
{
return m_nYear;
}
EmpLevel GetLevel() const
{
return m_nLevel;
}
virtual int GetSalary() = 0;
protected:
int GetWorkTime() const
{
time_t t = time(0);
struct tm* now = localtime(&t);
return now->tm_year + 1900 - m_nYear + 1;
}
protected:
string m_strName;
int m_nYear;
EmpLevel m_nLevel;
};
class Officer : public Employee
{
public:
Officer(string strName, int nYear):Employee(strName, nYear)
{
m_nLevel = enumOfficer;
}
public:
virtual int GetSalary() override
{
return GetWorkTime() * 5000;
}
};
class Staff : public Employee
{
public:
Staff(string strName, int nYear):Employee(strName, nYear)
{
m_nLevel = enumStaff;
}
public:
virtual int GetSalary() override
{
return GetWorkTime() * 1000;
}
};
const int MAX = 100000;
class SalarySys
{
public:
SalarySys() : m_strFileName("SalaryData_stl.txt")
{
Read();
}
~SalarySys()
{
Write();
for(Employee* p : m_vecEmp)
{
delete p;
}
m_vecEmp.clear();
}
private:
int Read()
{
string strName = "";
int nLevel = 0;
int nYear = 0;
int i = 0;
ifstream in(m_strFileName);
if(in.is_open())
{
while(true)
{
in>>strName>>nLevel>>nYear;
if(!in)
{
break;
}
if(enumOfficer == nLevel)
{
m_vecEmp[i] = new Officer(strName, nYear);
++i;
}
else if(enumStaff == nLevel)
{
m_vecEmp[i] = new Staff(strName, nYear);
++i;
}
if(i >= MAX)
{
break;
}
}
in.close();
}
cout<<"there is " << i << " employee" << endl;
}
void Write()
{
ofstream o(m_strFileName);
if (o.is_open())
{
for(Employee* p : m_vecEmp)
{
o<<p->GetName()<<"\t"<<p->GetLevel()<<"\t"<<p->GetYear()<<endl;
}
o.close();
}
}
public:
int Input()
{
cout<<"please input employee information(name, level(1-Officer,2-Staff) year) to add"<<endl;
cout<<"Eg:XiongDa 1 2008, -1 to finish input"<<endl;
while(true)
{
cout << "please input number "<<m_vecEmp.size() << " information: " <<endl;
string strName = "";
int nL = 0;
int nY = 0;
cin>>strName>>nL>>nY;
if(!cin)
{
cout<<"Error, please input again"<<endl;
cin.clear();
cin.sync();
continue;
}
else
{
if("-1" == strName)
{
break;
}
AddEmployee(strName, nL, nY);
}
}
return m_vecEmp.size();
}
Employee* GetMax()
{
auto maxit = max_element(m_vecEmp.begin(), m_vecEmp.end(),
[](Employee* a, Employee* b) -> bool
{
return a->GetSalary() < b->GetSalary();
});
if(m_vecEmp.end() != maxit)
{
return *(maxit);
}
else
{
return nullptr;
}
}
void Find()
{
while(true)
{
string strName = "";
cout<<"please input the name of employee(-1 to finish) to find:"<<endl;
cin>>strName;
if(!cin)
{
cout<<"input error, please input again"<<endl;
cin.clear();
cin.sync();
continue;
}
else if ("-1" == strName)
{
cout<<"find over, thanks!"<<endl;
break;
}
auto it = find_if(m_vecEmp.begin(), m_vecEmp.end(),
[=](Employee* emp) -> bool
{
return emp->GetName() == strName;
});
if(it != m_vecEmp.end())
{
cout<<"employee name:"<<(*it)->GetName()<<endl;
cout<<"employee salary:"<<(*it)->GetSalary()<<endl;
}
else
{
cout<<"can't find the name "<<strName<<endl;
}
}
}
private:
void AddEmployee(const string& strName, const int nL, const int nY)
{
if(enumOfficer == nL)
{
m_vecEmp.push_back(new Officer(strName, nY));
}
else if(enumStaff == nL)
{
m_vecEmp.push_back(new Staff(strName, nY));
}
}
private:
const string m_strFileName;
vector<Employee*> m_vecEmp;
};
int main()
{
SalarySys sys;
sys.Input();
Employee* pMax = sys.GetMax();
if(nullptr != pMax)
{
cout<<"the employee with the most high salary is: "<<endl;
cout<<"name: "<<pMax->GetName()<<endl;
cout<<"salary: "<<pMax->GetSalary()<<endl;
}
sys.Find();
return 0;
}