2014-02-24 101 views
0

stuType类别:替代strcmp()的,按字母顺序排序字符串

#include<iostream> 
#include<cstring> 

using namespace std; 

#ifndef STUTYPE 
#define STUTYPE 

class stuType { 

    private: 

    string fname; 
    string lname; 
    string social; 
    float gpa; 

    public: 

     stuType(void) { 

     fname = "no_fname"; 
     lname = "no_lname"; 
     social = "no_social"; 
     gpa = 0.0; 
     } 

     stuType(string fname_in, string lname_in, string social_in, float gpa_in) { 

     fname = fname_in; 
     lname = lname_in; 
     social = social_in; 
     gpa = gpa_in; 
     } 

    ~stuType() { 
     //Nothing needs to be added here. 
    } 

    void set_fname(string new_fname) { 
     fname = new_fname; 
    } 

    void set_lname(string new_lname) { 
     lname = new_lname; 
    } 

    void set_ssn(string new_ssn) { 
     social = new_ssn; 
    } 

    void set_gpa(float new_gpa) { 
     gpa = new_gpa; 
    } 

    string get_fname(void) { 
     return fname; 
    } 

    string get_lname(void) { 
     return lname; 
    } 

    string get_ssn(void) { 
     return social; 
    } 

    float get_gpa(void) { 
     return gpa; 
    } 

    friend istream & operator>>(istream &in, stuType &stu) { 
     in>>stu.fname; 
     in>>stu.lname; 
     in>>stu.social; 
     in>>stu.gpa; 

     return in; 
    } 

}; 

#endif 

Sort.cpp:

#include<iostream> 
#include<fstream> 
#include<cstdlib> 
#include<cstring> 

#include"stuType.h" 

using namespace std; 

/*Loads the elements of the object instance with data from the input file.*/ 
void load(istream &input, stuType Student[], int *size); 

/*Used in combination with the shellSort method to exchange the values of two variables in the class object.*/ 
void exchange(stuType &a, stuType &b); 

/*Sorts the objects in ascending order by comparing the values of the lname strings between object indices.*/ 
void shellSort(stuType Student[], int size); 

int main() { 

    stuType Student[10]; 

    int size; 

    char inputFile[200]; 
    char outputFile[200]; 

    ifstream input; 
    ofstream output; 

    cout<<"[INPUT_FILE]: "; 
    cin>>inputFile; 

    cout<<"[OUTPUT_FILE]: "; 
    cin>>outputFile; 

    input.open(inputFile); 
    output.open(outputFile); 

    if (input.fail()) { 
     cerr<<"\n[FILE] Error opening '"<<inputFile<<"'"<<endl; 
     exit(1); 
    } 

    if (output.fail()) { 
     cerr<<"\n[FILE] Error opening '"<<outputFile<<"'"<<endl; 
     exit(1); 
    } 

    load(input, Student, &size); 
    shellSort(Student, size); 

    return 0; 
} 

void load(istream &input, stuType Student[], int *size) { 

    int length = 0, i = 0; 

    float gpa; 
    string social; 
    string fname; 
    string lname; 

    while(input >> social >> fname >> lname >> gpa) { 
     cout<<"[Node::Load] Setting 'social' for index ["<<i<<"] to "<<social<<endl; 
     Student[i].set_ssn(social); 
     cout<<"[Node::Load] Setting 'fname' for index ["<<i<<"] to "<<fname<<endl; 
     Student[i].set_fname(fname); 
     cout<<"[Node::Load] Setting 'lname' for index ["<<i<<"] to "<<lname<<endl; 
     Student[i].set_lname(lname); 
     cout<<"[Node::Load] Setting 'gpa' for index ["<<i<<"] to "<<gpa<<endl; 
     Student[i].set_gpa(gpa); 
     cout<<"[Node::Load] Incrementing 'length'..."<<endl; 
     length++; 
     cout<<"[Node::Load] Incrementing 'i'..."<<endl; 
     i++; 
    } 

    cout<<"==================================="<<endl; 
    for (int i = 0; i<length; i++) { 
     cout<<"[ENTRY] Index: "<<i<<" | SSN: "<<Student[i].get_ssn()<<" | fname: "<<Student[i].get_fname()<<" | lname: "<<Student[i].get_lname()<<" | gpa: "<<Student[i].get_gpa()<<endl; 
    } 
    cout<<"==================================="<<endl; 

    *size = length; 
} 

void exchange(stuType &a, stuType &b) { 

    stuType *temp; 

    *temp = a; 
    a = b; 
    b = *temp; 

    delete temp; 
} 

void shellSort(stuType Student[], int size) { 

    int gap = size/2; 
    bool passOK; 

    while(gap>0) { 
     passOK = true; 

     for(int i = 0; i<size-gap; i++) { 
      if (strcmp(Student[i].get_lname(), Student[i+gap].get_lname)>0) { 
       cout<<"[Node::Sort] Exchanging Index ["<<i<<"] with Index ["<<i+gap<<"]..."<<endl; 
       exchange(Student[i], Student[i+gap]); 
       passOK = false; 
      } else if (strcmp(Student[i].get_lname(), Student[i+gap].get_lname())==0) { 
       if (strcmp(Student[i].get_fname(), Student[i+gap].get_fname())>0) { 
        cout<<"[Node::Sort] Exchanging Index ["<<i<<"] with Index ["<<i+gap<<"]..."<<endl; 
        exchange(Student[i], Student[i+gap]); 
        passOK = false; 
       } 
      } 
     } 

     if (passOK) { 
      gap /= 2; 
     } 
    } 
} 

的strcmp()期望接收的字符数组做比较,但因为我我正在使用字符串,我不能那样做。什么是替代方案?如果Student [i] .get_lname()大于Student [i + gap] .get_lname(),则变量'lname'需要进行比较并返回true。然后调用交换函数并交换对象局部变量的值。对象应根据'lname'变量的升序进行排序,'fname'变量只应在被比较的两个'lname'相同时引用。

+0

的strcmp需要被用于阵列,因为阵列进行比较以<或=只是比较存储位置,而不是内容。 std :: string会覆盖<和=来执行一些有用的操作,所以您可以使用<或=进行比较。 –

+0

你的setters接受一个字符串参数时应该使用'const string&'而不是一个字符串的副本。你为阅读学生定义了一个输入操作符;你为什么不使用它?你的'交换'函数是相当重量级的,是不是(至少和'{string t = a; a = b; b = t;}'相比,并没有使用C++ 11'swap'技术 - std :: swap(a,b)')? –

回答

1

C++串提供implementations of operators < and >,所以可以代替使用它们的strcmp

std::string a = "hello"; 
std::string b = "world"; 
if (a < b) { 
    cout << a << " is less than " << b << endl; 
} 
+0

因此,如果我不完全使用strcmp(),只是比较使用< >或==的两个字符串,那么它会按字母顺序排列它们? –

+0

@AdamChubbuck,按字母顺序,实际上,但足够接近。 – chris

+1

@AdamChubbuck'<' and '>'以字典顺序比较字符串,并区分大小写。由于大写和小写字符用ASCII表示的方式,任何大写字符都会在小写字符之前排序(例如'Z' <''a')。 – dasblinkenlight