2014-02-24 100 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