C++ 기말고사 준비 (string)

Jaewoong2·2020년 11월 30일
0

C++

목록 보기
10/13
#include<iostream>
#include<string>
using namespace std;

// 앨범 클래스를 만듭니다.
// 앨범 클래스를 만듭니다. 정렬하는 함수를 제외하고 모든 함수를 다 private 로 숨겨줍니다.
// 0. 제목과 작곡가가 써있는 문장에서 띄어쓰기가 중복되어 있으면 하나로 줄이고
// 0. 제목에 붙어있는 1. 과 같은 순서 번호는 제거 합니다.
// 0. (-) 대시 문자가 ( 제목 - 작곡가 ) 로 쓰이지 않고, 다른 곳에 있으면 공백으로 바꿉니다.
// 0. 또한 제목에 붙어있는 (-)대시 문자는 제목에 한번 띄어쓰기를 하고 (-)대시문자가 오도록 합니다
// 1. 작곡가의 두번째 이름에 맞춰서 작곡가의 이름을 재 배열 합니다. ( 작곡가의 성 뒤로 이름이 오도록 )
// 2. 하지만 작곡가의 이름이 없을 경우 (no author listed) 에는 작곡가의 이름이 재배열되지 않도록 합니다.
// 3. 작곡가의 이름에 맞춰 알파벳 순으로 배열을 정렬을 한 후, 음악 제목 또한 a, an, the
// 같은 관사를 제외한 앞글자에 맞춰서 알파벳 순으로 배열을 재 정렬합니다.

class Album {
public:
    void sortFunc(const int& size, string returnArray[]);
    // 음악을 정렬하는 함수 입니다.
    // 파라미터로 음악의 갯수와, 정렬된 배열로 받아올 배열을 넣습니다.
private:
    string strRemovedIndex(const string& songStr);
    // 음악 제목에있는 인덱스번호를 지우는 함수입니다.
    void findBlankAndTrim(string& songStr);
    // 음악 제목에 있는 공백들을 하나로 줄이는 함수입니다.
    void eraseDash(string& str);
    // 제목과 작곡가 사이에 있는 대쉬를 제외한 대쉬를 공백으로 바꾸는 함수 입니다.
    string authorNameChange(string str);
    // 작곡가의 이름을 [성 이름] 순으로 바꾸는 함수 입니다.
    void authorSorting(string str[], const int& size);
    // 작곡가의 이름을 알파벳순으로 정렬하는 함수 입니다.
    void titleSorting(string str[], const int& size);
    // 제목의 이름을 알파벳 순으로 정렬하는 함수 입니다.
    const string songArray[9] = { "1. Adagio \"MoonLight\" Sonata- Ludwig Van Beethoven",
                                  "2. An Alexis- F.H.Hummel and J.N.Hummel",
                                  "3. A La-     Bien Aimee- Ben Schutt",
                                  "4. At Sunset- E. MacDowell",
                                  "5. Angelus-    J.Massenet",
                                  "6. Anitra\'s Dance- Edward Grieg",
                                  "7. Erin is my Home- no author listed",
                                  "8. Ase's- Death- Edward Grieg",
                                  "9. The Brain Death - no author listed",
    };
    // 음악배열 입니다.
};

int main() {
    Album songs;
// 메인 함수에서는, 앨범 클래스를 하나 만들고,
    string sortedSongArray[9];
// 정렬된 배열을 받을 string 배열을 하나 선언 합니다.
    songs.sortFunc(9, sortedSongArray);
// 앨범클래스 인스턴스를 정렬하여 sortedSongArray 에 넣어줍니다.

    for(int i = 0; i < 9; i++)
        cout << sortedSongArray[i] << "\n";
    // 정렬된 배열을 출력하는 반복문 입니다.

    return 0;
};


void Album::sortFunc(const int& size, string returnArray[]) {
    // 음악앨범을 정렬하는 함수 입니다.
    // 앞서 0 - 3으로 계획한것과 같은 것을 실행하는 함수 입니다.

    for(int i = 0; i < size; i++) {
        returnArray[i] = strRemovedIndex(songArray[i]);
        // strRemovedIndex는, 인덱스번호를 지운 string을 반환 하는 함수 입니다.
        // strRemovedIndex 함수 안에 중복되는 빈 공간을 하나로 줄이고
        // 대쉬문자를 하나만 남기는 함수가 있습니다.
        // 음악앨범의 길이만큼 반복문을 반복하며,
        // 정렬된 배열을 넣어줄 배열의 요소에 하나씩 제목의 인덱스번호를 지워서 string을 넣어줍니다.
    }

        titleSorting(returnArray, size);
    // 음악앨범에 있는 것들을 재 정렬 하는 함수 입니다.
    // 여기서 작곡가의 이름을 재배열하고, 작곡가의 이름을 알파벳 순서에 맞춰서 재배열하고,
    // 그 후 제목의 이름을 알파벳 순서에 맞춰서 재배열 하는 함수가 있습니다.
}

string Album::strRemovedIndex(const string& songStr) {
    string newSongStr = songStr.substr(songStr.find('.') + 2);
    // 인덱스번호를 없애고 반환하기 위한 string 값에 넣어줍니다.

    findBlankAndTrim(newSongStr);
    // 반환 하기 위한 string 값을 파라미터 값으로 받아서 중복된 공백을 줄여줍니다.
    eraseDash(newSongStr);
    // 반환 하기 위한 string 값을 파라미터 값으로 받아서 중복된 대쉬 문자를 줄여줍니다.

    return newSongStr;
    // 인덱스번호를 없애고 중복된 공백과 대쉬문자를 줄인 새로운 음악을 반환 합니다.
    // 이는 정렬될 배열의 요소로 들어갑니다.
}

void Album::findBlankAndTrim(string& songStr) {
    for(int i = 0; i < songStr.length(); i++) {
        if(i + 1 < songStr.length()) {
         while(songStr[i] == ' ' && songStr[i + 1] == ' ') {
             string newSongStr = songStr.substr(0, i) + songStr.substr(i + 1);
             songStr = newSongStr;
            }
        }
    }
    // 문장을 반복하며 빈 공간을 찾습니다.
    // 빈공간 다음에 빈 공간이 또 있으면 그 만큼 하나를 줄여줍니다.
    // 빈공간 다음에 빈 공간이 없을 때 까지 반복합니다. (한번 빈공간이 나오면 빈공간이 하나밖에 안나오도록)
}

void Album::eraseDash(string& str) {
    int count = 0;
    int index = -1;
    int lastIndex;
    string newStr = str;

    for(int i = 0; i < str.length(); i++){
        if(str[i] == '-') {
            count++;
            lastIndex = i;
        }
    };

    // 제목과 작곡가 사이에 있는 - 는 항상 모든 - 문자 뒤에 있습니다
    // 이를 통해서 맨마지막에 있는 - 의 index 번호를 lastIndex 로 받습니다.

    for(int i = 0; i < str.length(); i++) {
        if(str[i] == '-') {
            index = i;
            if(count > 1 && index != lastIndex) {
                newStr = str.substr(0, i) + str.substr(i + 1, str.length());
            }
            // lastIndex 가 아닌 곳에 있는 - 를 지워줍니다.
        }
    }

    for(int i = 0; i < newStr.length(); i++) {
        if(newStr[i] == '-') {
            index = i;
        }
    } // - 문자가 있는 곳의 위치를 받습니다. (find 함수를 사용해도 됨)

    if(newStr.substr(index, 1) == "-") {
        if(newStr[index - 1] == ' ') {
            newStr = newStr.substr(0, index) + "-" + newStr.substr(index + 1, newStr.length());
        } else {
            newStr = newStr.substr(0, index) + " -" + newStr.substr(index + 1, newStr.length());
        }
        // 대쉬문자 뒤에 공백이 있으면 제목과 띄어주지 않고,
        // 대쉬문자와 제목이 붙어 있으면 띄워 줍니다.
    }
    str = newStr;
    // 대쉬문자를 줄이고 제목과 띄운 문자를 원래 문장에 대입 해줍니다.
}

void Album::titleSorting(string str[], const int& size) {
    // 제목과 작곡가를 정렬하는 함수 입니다.
    authorSorting(str, size);
    // 작곡가의 이름을 재배열하고 알파벳순으로 재 정렬 하는 함수 입니다.
    string aAnThe[6] = {"a ", "A ", "an ", "An ", "the ", "The "};
    // 관사 문장이 들어 있는 배열 입니다.
    const int anAnTheLength = 6;
    // 관사 문장이 들어 있는 배열의 길이 입니다.
    string titleArray[size];
    // 관사 문장 다음에 들어 있는 제목 또는 제목의 첫 글자들의 배열입니다.

    for(int i = 0; i < size; i++) {
        for(int j = 0; j < anAnTheLength; j++) {
            int index = str[i].find(aAnThe[j]);
            if(index < str[i].length() && index == 0) {
                    switch (j) {
                        case 0:
                        case 1:
                            titleArray[i] = str[i].substr(index + 2, 1);
                            break;
                            // 관사가 A일때, 배열의 순서에 맞춰서 첫글자가 들어있을 배열에 넣어줍니다
                        case 2:
                        case 3:
                            titleArray[i] = str[i].substr(index + 3, 1);
                            break;
                            // 관사가 An 일때, 배열의 순서에 맞춰서 첫글자가 들어있을 배열에 넣어줍니다
                        case 4:
                        case 5:
                            titleArray[i] = str[i].substr(index + 4, 1);
                            break;
                            // 관사가 The 일때, 배열의 순서에 맞춰서 첫글자가 들어있을 배열에 넣어줍니다
                        default:
                            break;
                    }
            }
        }
        if(titleArray[i].length() == 0) {
            titleArray[i] = str[i].substr(0, 1);
        }
        // 만약 관사가 없으면, 제목의 맨 첫 글자를 첫 글자 배열에 넣어 줍니다.
    }

    for(int i = 0; i < size; i++) {
        for(int j = i + 1; j < size; j++) {
            if(titleArray[i].compare(titleArray[j]) > 0) {
                string tempChar = titleArray[i];
                titleArray[i] = titleArray[j];
                titleArray[j] = tempChar;

                string tempStr = str[i];
                str[i] = str[j];
                str[j] = tempStr;
            }
        }
    }
    // 정렬 알고리즘을 통해서 알파벳 순서로 정렬을 해줍니다.
}

void Album::authorSorting(string str[], const int& size) {
    string newStr;
    for(int i = 0; i < size; i++) {
        int index = str[i].find('-');
        newStr = str[i].substr(0, index + 1) + authorNameChange(str[i].substr(index + 1));
        // 제목과 작곡가의 이름을 분리 시켜서 작곡가의 이름은 authorNameChange 를 통해서 순서를 바꾸고  그것 과
        // 원 제목을 더해서 새로운 문장으로 넣어줍니다.
        for(int j = 0; j < newStr.length(); j++) {
            if(newStr[j] == '-' && newStr[j + 1] != ' ') {
                newStr.replace(j + 1, newStr.length()," " + newStr.substr(j + 1));
                // 대쉬문자 다음에 띄어져있지 않으면 공백을 넣어줍니다.
            }
        }
        str[i] = newStr;
        // 반복문으로 새로운 작곡가의 이름을 정렬될 배열의 요소 값으로 각각 넣어줍니다.
    }


    for(int i = 0; i < size; i++) {
        for(int j = i + 1; j < size; j++) {
            basic_string<char> iChar;
            basic_string<char> jChar;
            int iIndex = str[i].find('-');
            int jIndex = str[j].find('-');
            iChar = str[i].substr(iIndex + 2).substr(0,1);
            jChar = str[j].substr(jIndex + 2).substr(0,1);
            if(iChar > jChar) {
                string temp = str[i];
                str[i] = str[j];
                str[j] = temp;
            }
        }
    }
    // 정렬 알고리즘을 통해, 알파벳 순서에 맞춰서 재 정렬을 해줍니다.

    for(int i = 0 ; i < size; i++) {
        int iIndex = str[i].find('-');
        if (str[i].substr(iIndex + 2) == "no author listed") {
            string temp = str[i];
            str[i] = str[size - 1];
            str[size - 1] = temp;
        }
    }
    // 만약 작곡가의 이름이 no author listed 이면, 배열의 맨 뒤로 옮깁니다.
};

string Album::authorNameChange(const string str) {
    // 작곡가의 이름을 [성 이름] 순으로 바꿔주는 함수 입니다.
    int lastIndex;
    string newStr;

    if(str.find("and") < str.length()) {
        return authorNameChange(str.substr(0, str.find(" and"))) + " and " + authorNameChange(str.substr(str.find("and") + 3));
    }
    // 만약에 이름에 and 가 들어 있으면 and 앞 뒤로 나눠서 성과 이름의 순서를 바꾸고 다시 합친 값을 반환 합니다.
    // and 앞 각각은 재귀하여 순서를 바꿉니다. (and 가 들어 있지 않고, string 값으로 반환 하기 때문에 가능)

    if(str.find('.') < str.length()) {
        for(int i = 0; i < str.length(); i++) {
            if(str[i] == '.') {
                lastIndex = i;
         }
        }
        return str.substr(lastIndex + 1) + str.substr(0, lastIndex + 1);
    } else {
        if(str != " no author listed") {
            for(int i = 0; i < str.length(); i++) {
                if (str[i] == ' ') {
                    lastIndex = i;
                }
            }
            return str.substr(lastIndex, str.length()) + str.substr(0, lastIndex);
        }
        return str;
    }
    // . 으로 성과 이름을 구분 하거나, 공백으로 구분을 하는데 케이스를 .이 있을 때와 공백이 있을 때 로 나눕니다.
    // 성과 이름을 바꾸고나서 그 문자열을 반환 합니다. 이는 정렬될 배열의 각각의 문장요소에 넣어집니다.
    // 만약 작곡가의 이름이 no author listed 이면 그대로 반환 합니다.
}


profile
DFF (Development For Fun)

0개의 댓글