【问题标题】:implement member function (sorting)实现成员函数(排序)
【发布时间】:2016-10-14 18:28:44
【问题描述】:

我需要使用成员函数(我相信在我的 Date 结构中)按照最早入院的顺序对医院人员进行排序,然后再从列表中向下排序。我可以简单地添加一个 Sorting();我的 Date 结构中的“函数”与我的 printHospitalPersonnel 函数相关联,并在调用排序菜单选项时打印出有序列表?下面是我的代码,谢谢!

#include <iostream>
#include <iomanip> 
#include <fstream> 
#include <string.h> 
#include <cstdlib>
using namespace std;

/*
Structure to store the date
*/
struct Date
{
    int month;
    int day;
    int year;
};

/*
Structure to store HospitalPersonnels data
*/
struct HospitalPersonnel
{
    string firstname;
    string lastname;
    string ID;
    string role;

    string dutyDay0;
    string dutyDay1;
    string dutyDay2;

    //for patients
    char exitFlag;
    Date admitDate;
    Date exitDate;
};

HospitalPersonnel* readHospitalPersonnelFromFile(int &totalHospitalPersonnels);
void menu(HospitalPersonnel *hospitalPersonnel, int totalHospitalPersonnel);
void printHorizontalLine( int width, char border_char );
void printHospitalPersonnel(HospitalPersonnel *hospitalPersonnel, int totalHospitalPersonnel, string roleFlag, char patientExitFlag);
string getFullNameForDay(string dayAbbreviation);

/*
* Entry point
*/
int main()
{
    HospitalPersonnel *allHospitalPersonnel;
    int totalHospitalPersonnel = 0;
    allHospitalPersonnel = readHospitalPersonnelFromFile(totalHospitalPersonnel);

    if( allHospitalPersonnel == NULL )
    {
        cout << "allHospitalPersonnel is NULL" << endl;
        return 0;
    }

    printHospitalPersonnel(allHospitalPersonnel, totalHospitalPersonnel , "", ' ');
    menu(allHospitalPersonnel, totalHospitalPersonnel);

    return 0;
}



/*
* Responsible for reading HospitalPersonnel records from hospitalPersonnel.txt into HospitalPersonnel array of structs
*
*
* @param totalHospitalPersonnel: reference variable which post execution, contains size of HospitalPersonnel
* @param return: pointer pointing to the array of structs containing HospitalPersonnel data
*/
HospitalPersonnel* readHospitalPersonnelFromFile(int &totalHospitalPersonnel)
{
    char delimiter;
    HospitalPersonnel *allHospitalPersonnelPointer;
    //input stream for HospitalPersonnels data
    ifstream allHospitalPersonnelInFile;

    //open HospitalPersonnels file
    allHospitalPersonnelInFile.open("hospitalPersonnel.txt");

    //error handling in case file does not exist - start
    if( !allHospitalPersonnelInFile )
    {
        cout << "Error opening hospitalPersonnel.txt" << endl;
        return NULL;
    }
    //error handling in case file does not exist - end
    cout << "Success opening hospitalPersonnel.txt" << endl;
    allHospitalPersonnelInFile >> totalHospitalPersonnel;
    allHospitalPersonnelPointer = new HospitalPersonnel[totalHospitalPersonnel];

    cout << "totalHospitalPersonnels: " << totalHospitalPersonnel << endl;

    for(int i = 0; i < totalHospitalPersonnel; i++)
    {
        allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].firstname;
        allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].lastname;
        allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].ID;
        allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].role;

        if( allHospitalPersonnelPointer[i].role != "PT" )
        {
            // this is a Doctor or a Nurse Practitioner
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].dutyDay0;
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].dutyDay1;
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].dutyDay2;

            allHospitalPersonnelPointer[i].dutyDay0 = getFullNameForDay(allHospitalPersonnelPointer[i].dutyDay0);
            allHospitalPersonnelPointer[i].dutyDay1 = getFullNameForDay(allHospitalPersonnelPointer[i].dutyDay1);
            allHospitalPersonnelPointer[i].dutyDay2 = getFullNameForDay(allHospitalPersonnelPointer[i].dutyDay2);
        }
        else
        {
            // this is a Patient
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].exitFlag;

            // admit date
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].admitDate.month;
            allHospitalPersonnelInFile >> delimiter;
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].admitDate.day;
            allHospitalPersonnelInFile >> delimiter;
            allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].admitDate.year;

            if( allHospitalPersonnelPointer[i].exitFlag == 'Y' )
            {
                // this Patient has exit the hospital
                allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].exitDate.month;
                allHospitalPersonnelInFile >> delimiter;
                allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].exitDate.day;
                allHospitalPersonnelInFile >> delimiter;
                allHospitalPersonnelInFile >> allHospitalPersonnelPointer[i].exitDate.year;
            }
        }
    }

    allHospitalPersonnelInFile.close();

    return allHospitalPersonnelPointer;
}

/*
* Responsible for printing menu and handling user selection
*
*
* @param hospitalPersonnel: pointer pointing to the array of structs containing Hospital Personnel data
* @param totalHospitalPersonnel: size of hospitalPersonnel
*/

void menu(HospitalPersonnel *hospitalPersonnel, int totalHospitalPersonnel)
{
    int input;
    while( true )
    {
        cin >> input;
        switch( input )
        {
            case 0:
                // Press 0 to print all Hospital Personnel
                printHospitalPersonnel(hospitalPersonnel, totalHospitalPersonnel, "", ' ');
                break;
            case 1:
                // Press 1 to print only Patients
                printHospitalPersonnel(hospitalPersonnel, totalHospitalPersonnel, "PT", ' ');
                break;
            case 2:
                // Press 2 to print only Doctors
                printHospitalPersonnel(hospitalPersonnel, totalHospitalPersonnel, "MD", ' ');
                break;
            case 3:
                // Press 3 to print only Nurse Practitioners
                printHospitalPersonnel(hospitalPersonnel, totalHospitalPersonnel, "NP", ' ');
                break;
            case 4:
                // Press 4 to print only Admitted Patients
                printHospitalPersonnel(hospitalPersonnel, totalHospitalPersonnel, "", 'N');
                break;
            case 5:
                // Press 5 to print only non-Admitted Patients
                printHospitalPersonnel(hospitalPersonnel, totalHospitalPersonnel, "", 'Y');
                break;
            case 6:
                // Press 6 to exit
                exit(0);
        }

    }
}

/*
* Responsible for converting the initial for a day to the full name
*
*
* @param dayAbbreviation: short name for day
* @param return: long name for day
*/
string getFullNameForDay(string dayAbbreviation)
{
    if( dayAbbreviation == "M" )
        return "Mondays";
    else if( dayAbbreviation == "T" )
        return "Tuesdays";
    else if( dayAbbreviation == "W" )
        return "Wednesdays";
    else if( dayAbbreviation == "TH" )
        return "Thursdays";
    else if( dayAbbreviation == "F" )
        return "Fridays";
    else if( dayAbbreviation == "SA" )
        return "Saturdays";
    else if( dayAbbreviation == "SU" )
        return "Sundays";

    return "";
}

/*
* Responsible for printing the HospitalPersonnel array of structs
*
*
* @param hospitalPersonnel: pointer pointing to the array of structs containing HospitalPersonnel data
* @param totalHospitalPersonnel: size of hospitalPersonnel
*/
void printHospitalPersonnel(HospitalPersonnel *hospitalPersonnel, int totalHospitalPersonnel, string roleFlag = "", char patientExitFlag = ' ')
{
    if( hospitalPersonnel == NULL || totalHospitalPersonnel < 1 )
    {
        return;
    }

    cout << endl;
    printHorizontalLine(85, '*');
    printHorizontalLine(85, '*');
    for(int i = 0; i < totalHospitalPersonnel; i++)
    {

        if( roleFlag.length() != 0 )
        {
            if( roleFlag != hospitalPersonnel[i].role )
            {
                // skip roles which do not match roleFlag
                continue;
            }
        }

        if( patientExitFlag != ' ' )
        {
            if( patientExitFlag != hospitalPersonnel[i].exitFlag )
            {
                continue;
            }
        }

        // filter - end

        cout.clear();
        cout.fill(' ');

        cout
        << left
        << setw(3)
        << i
        << left << setw(10)
        << hospitalPersonnel[i].firstname
        << left << setw(10)
        << hospitalPersonnel[i].lastname

        << left << setw(15)
        << hospitalPersonnel[i].ID
        << left << setw(10)
        << hospitalPersonnel[i].role;


        if( hospitalPersonnel[i].role != "PT" )
        {
            // this is a Medical staff
            cout
            << hospitalPersonnel[i].dutyDay0
            << "-"
            << hospitalPersonnel[i].dutyDay1
            << "-"
            << hospitalPersonnel[i].dutyDay2;
        }
        else
        {
            cout << hospitalPersonnel[i].exitFlag << "\t";
            cout
            << right <<setw(2) << setfill('0')
            << hospitalPersonnel[i].admitDate.month
            << ":"
            << right <<setw(2) << setfill('0')
            << hospitalPersonnel[i].admitDate.day
            << ":"
            << right <<setw(2) << setfill('0')
            << hospitalPersonnel[i].admitDate.year
            << "\t";

            if( hospitalPersonnel[i].exitFlag == 'Y' )
            {
                cout
                << right <<setw(2) << setfill('0')
                << hospitalPersonnel[i].exitDate.month
                << ":"
                << right <<setw(2) << setfill('0')
                << hospitalPersonnel[i].exitDate.day
                << ":"
                << right <<setw(2) << setfill('0')
                << hospitalPersonnel[i].exitDate.year;
            }
        }

        cout << endl;
    }
    printHorizontalLine(85, '*');
    printHorizontalLine(85, '*');
    cout << endl;
    cout << "Press 0 to print all Hospital Personnel" <<endl;
    cout << "Press 1 to print only Patients" << endl;
    cout << "Press 2 to print only Doctors" << endl;
    cout << "Press 3 to print only Nurse Practitioners" << endl;
    cout << "Press 4 to print only Admitted Patients" << endl;
    cout << "Press 5 to print only non-Admitted Patients" << endl;
    cout << "Press 6 to exit: ";
}


/*
* Responsible for printing a horizontal line which consists of border_char characters
*
*
* @param width: count of border_char
* @param border_char: width made out of characters
*/
void printHorizontalLine( int width, char border_char )
{
    cout.fill( border_char );
    cout << setw( width ) << border_char << "\n";
    cout.fill(' ');
}

【问题讨论】:

  • 如果我理解正确,您想通过admitDateHospitalPersonnel* 向量中的条目进行排序。所以基本上你想对一个向量进行排序。使它成为Date 的成员函数对我来说没有逻辑意义。但是,您可以做到。也许你可以澄清你的问题。你有什么问题?如何创建成员函数?如何实现排序? “绑定到 printHospitalPersonnel 功能”是什么意思?
  • 我遇到的问题是我想添加一个用于排序的菜单选项并实现一个新的成员功能,它将医院人员从最新入院的病人到最老的病人,然后是医生和护士。我不知道应该在哪里添加它以及如何设置它

标签: c++ member-functions


【解决方案1】:

典型的做法是实现operator&lt;,基本上有一个islessthan函数,使用模板化的free函数进行排序。如果作业允许,std::sort 已经编写好并可供您使用。如果不使用&lt; 编写您自己的排序函数来对数据进行排序。

bool operator< (const Date& lhs, const Date& rhs)
{ 
    // code goes here
}

Dates 和std::sort 对数组进行排序非常简单:

std::sort(dates, dates+number_of_dates);

不过……

您不想对Dates 进行排序。您想对HospitalPersonnel 进行排序。并且HospitalPersonnel 有两个Dates 以及名字和姓氏、ID 和角色进行排序。幸运的是 std::sort 允许您指定一个比较器函数来定义您想要排序的内容。如果您必须编写自己的排序,我建议您遵循此模型,因为它允许您编写一个排序函数并以不同的方式调用它。

例如:

bool compareAdmitDate(const HospitalPersonnel &rhs, const HospitalPersonnel &lhs)
{
    return rhs.admitDate < lhs.admitDate;
}

bool compareLastName(const HospitalPersonnel &rhs, const HospitalPersonnel &lhs)
{
    return rhs.lastname< lhs.lastname;
}

这些与

一起使用
std::sort(allHospitalPersonnelPointer, 
          allHospitalPersonnelPointer + totalHospitalPersonnel,
          compareAdmitDate);

一个警告:std::sort 将对提供的列表进行适当的排序。如果您不想对列表进行排序,请复制列表,然后排序并返回副本。

【讨论】:

  • 那么我应该将我的两个结构组合成一个类,然后将 bool compareAdmitDate 添加到 struct Date 并将 bool compareLastName 添加到 struct HopsitalPersonnel?我也想打电话
  • std::sort(allHospitalPersonnelPointer, allHospitalPersonnelPointer + totalHospitalPersonnel, compareAdmitDate);
  • 我很抱歉,我一直在意外按回车.....所以在将相应的语句放入结构后,我将声明 std::sort 作为排序菜单会执行的操作选项是用户输入的?
  • 你不必组合任何东西。 HopsitalPersonnel 已经包含 Date,所以最好继续前行。您只需要为Date 实现operator&lt;。上面的compareAdmitDate 示例知道如何使用admitDateoperator&lt;
  • struct HospitalPersonnel { string firstname;字符串姓氏;字符串标识;字符串角色;字符串 dutyDay0;字符串 dutyDay1;字符串 dutyDay2; //对于患者 char exitFlag;日期录取日期;日期退出日期; bool compareAdmitDate(const HospitalPersonnel &rhs, const HospitalPersonnel &lhs) { return rhs.admitDate
【解决方案2】:

像这样? @user4581301

struct HospitalPersonnel
{
    string firstname;
    string lastname;
    string ID;
    string role;

    string dutyDay0;
    string dutyDay1;
    string dutyDay2;

    //for patients
    char exitFlag;
    Date admitDate;
    Date exitDate;

    bool compareAdmitDate(const HospitalPersonnel &rhs, const HospitalPersonnel &lhs)
    {
        return rhs.admitDate < lhs.admitDate;
    }
    bool compareLastName(const HospitalPersonnel &rhs, const HospitalPersonnel &lhs)
    {
        return rhs.lastname < lhs.lastname;
    }
    std::sort(HospitalPersonnel, HospitalPersonnel + totalHospitalPersonnel, compAdmitDate);
};

【讨论】:

  • 它告诉我禁止声明没有类型的“排序”
  • 这两个函数不需要是类的一部分,std::sort 应该从请求排序的菜单项所在的任何位置调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-29
  • 2020-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-22
相关资源
最近更新 更多