ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 프로그래머스 Lv2 브라이언의 고민
    Computer Science/프로그래머스 2023. 10. 8. 16:09

    첫번째로 나는 (규칙1, 규칙2, 규칙1 + 규칙2)의 조건을 검사하기로 했다.
    첫번째 문자가 대문자이면 규칙1
    첫번째 문자가 소문자이면 규칙2

    규칙 1일 경우
    if (isupper(sentence[i])) 
    {
        word += sentence[i];
        first_rule = true;
    
        if (i + 1 == sentence.length()) 
        {
            first_rule = false;
            words.push_back(word);
            word = "";
        }
        else if (isupper(sentence[i + 1])) 
        {
            first_rule = false;
            words.push_back(word);
            word = "";
        }
        else if (islower(sentence[i + 1])) 
        {
            if (checked[sentence[i + 1] - 'a'])
                return invalid;
            char_rule1 = sentence[i + 1];
            vector<int> pos;
            for (int j = i + 1; j < sentence.length(); ++j) 
                if (sentence[j] == char_rule1)
                    pos.push_back(j);
            if (pos.size() == 1)
                continue;
            else if (pos.size() >= 3) 
            {
                bool flag = true;
                for (int j = 1; j < pos.size(); ++j) 
                {
                    if (pos[i + 1] - pos[i] != 2) 
                    {
                        flag = false;
                        break;
                    }
                }
                if (flag)
                    continue;
            }
            else 
            {
                first_rule = false;
                char_rule1 = NULL;
                words.push_back(word);
                word = "";
            }
        }
    }
    1. 문자열이 끝이라면 대문자 한 문자만 온 것이므로 워드안에 넣는다. 'O'
    2. 다음 문자열도 대문자라면 한 문자로 끝난 것이므로 워드안에 넣는다.
    3. 다음 문자가 소문자라면 다음 문자가 사용 된 소문자인지 확인하고, 검사 소문자에 넣은 후 소문자 위치를 저장한다.
    3-1. 소문자가 1개이면 "OaO"이므로 다음 검사 때 대문자 한 문자만 Word에 넣고 검사 끝
    3-2. 소문자가 3개 이상이면 문자의 간격이 2인지 확인한다. 문자의 간격이 2가 아니라면 flag = false로 만드는데,,
    이 코드는 삭제해도 테스트 케이스를 성공했다.
    if (pos.size() == 1)
        continue;​

    4. 위 코드가 이해가 안갔는데, 저장한 위치가 1개이면 ex) 0a0 꼴이므로 
    else if (first_rule)​
    로 넘어가 규칙성을 검사한 후 워드에 넣는다.

    규칙2의 경우
    1. 사용한 검사 문자인지 확인
    2. 문자가 끝났는지 확인 "a"를 생각하자.
    3. 다음 문자가 소문자인지 검사한다. "aa"는 규칙에 위배되므로
    위 조건에 해당하면 오류문자를 리턴한다.
    if (islower(sentence[i])) 
    {
        if (checked[sentence[i] - 'a'])
            return invalid;
        if (i + 1 == sentence.length())
            return invalid;
        else if (islower(sentence[i + 1]))
            return invalid;
        second_rule = true;
        char_rule2 = sentence[i];
    }​
    else if (first_rule) 
    {
        if (isupper(sentence[i])) 
        {
            word += sentence[i];
    
            if (i + 1 == sentence.length()) 
            {
                first_rule = false;
                checked[char_rule1 - 'a'] = true;
                char_rule1 = NULL;
                words.push_back(word);
                word = "";
            }
            else if (isupper(sentence[i + 1])) 
            {
                first_rule = false;
                checked[char_rule1 - 'a'] = true;
                char_rule1 = NULL;
                words.push_back(word);
                word = "";
            }
            else if (char_rule1 != sentence[i + 1]) 
            {
                first_rule = false;
                checked[char_rule1 - 'a'] = true;
                char_rule1 = NULL;
                words.push_back(word);
                word = "";
            }
        }
        if (islower(sentence[i])) 
        {
            if (i + 1 == sentence.length())
                return invalid;
            else if (islower(sentence[i + 1]))
                return invalid;
        }
    }
    첫번째 규칙을 검사하는 코드이다. 
    대문자 일 때는
    1. 다음 문자가 문자열의 끝이라면 규칙1 검사를 끝낸다.
    2. 다음 문자가 대문자여도 규칙1 검사를 끝낸다.
    3. 다음 문자가 소문자 규칙이 아니여도 규칙1 검사를 끝낸다.
    first_rule = false; // 규칙 1 OFF
    checked[char_rule1 - 'a'] = true; // 이제 다른 새 단어에서 이번 규칙 1 에 쓰인 소문자(특수문자)를 다신 쓸 수 없도록 체크
    char_rule1 = NULL; // 리셋
    words.push_back(word); // 단어 추가
    word = ""; // 리셋​

     

    검사를 끝내는 코드이다. 
    검사를 분기하는 변수를 끄고
    검사 문자를 비워주고
    해당 문자를 검사했다는것을 체크하고
    word를 정답에 삽입 후 word를 비워준다.

    소문자 일 때는
    규칙1은 대문자로 끝나야하는데  끝나버린 것이므로
    if (i + 1 == sentence.length())
        return invalid;​

     

    위 코드를 넣어준다. 

    또한 규칙1은 소문자가 연달아 올 수 없으므로 
    else if (islower(sentence[i + 1]))
        return invalid;​

     

    다음 문자가 소문자인지 검사한다.


    else if (second_rule) 
    {
        if (isupper(sentence[i])) 
        {
            word += sentence[i];
    
            if (i + 1 == sentence.length())
                return invalid;
            else if (islower(sentence[i + 1]) && char_rule2 != sentence[i + 1]) 
            {
                if (char_rule2 == sentence[i - 1]) 
                {
                    if (checked[sentence[i + 1] - 'a'])
                        return invalid;
                    first_rule = true;
                    char_rule1 = sentence[i + 1];
                }
                else
                    return invalid;
            }
        }
        if (islower(sentence[i])) 
        {
            second_rule = false;
            checked[char_rule2 - 'a'] = true;
            char_rule2 = NULL;
            words.push_back(word);
            word = "";
        }
    }
    현재 대문자가 문자열의 끝인지 검사한다.
    규칙2는 "aHa"꼴로 끝나야하기 때문이다.

    다음 문자가 소문자인데, 규칙2 검사 문자와 다르고, 이전 문자가 규칙2 검사 문자라면
    else if (islower(sentence[i + 1]) && char_rule2 != sentence[i + 1]) 
    {
        if (char_rule2 == sentence[i - 1]) 
        {
            if (checked[sentence[i + 1] - 'a'])
                return invalid;
            first_rule = true;
            char_rule1 = sentence[i + 1];
        }
        else
            return invalid;
    }​


    두번째 규칙 검사 중 다음 문자가 검사2 문자가 아닌 다른 문자라면 규칙1이 적용되기 시작했다는 것이다.
    마찬가지로 사용한 검사 문자열인지 확인하고 규칙1 검사가 시작했다는 것을 코드로 짜면된다.

    "aHbEbLbLbOacWdOdRdLdDc"에서 "aHb"같은 부분이다.
    if (islower(sentence[i])) 
    {
        second_rule = false;
        checked[char_rule2 - 'a'] = true;
        char_rule2 = NULL;
        words.push_back(word);
        word = "";
    }​

    규칙2 검사 중 다음 문자가 소문자이면 규칙2 검사를 종료하면 된다.

    규칙1과 규칙2를 동시에 검사하는 코드이다.

    if (first_rule && second_rule) {
        if (isupper(sentence[i])) {
            word += sentence[i];
    
            if (i + 1 == sentence.length())
                return invalid;
            else if (isupper(sentence[i + 1]))
                return invalid;
            else if (char_rule1 != sentence[i + 1] && char_rule2 != sentence[i + 1])
                return invalid;
        }
        if (islower(sentence[i])) {
            if (char_rule2 == sentence[i]) {
                first_rule = false;
                checked[char_rule1 - 'a'] = true;
                char_rule1 = NULL;
    
                second_rule = false;
                checked[char_rule2 - 'a'] = true;
                char_rule2 = NULL;
    
                words.push_back(word);
                word = "";
    
                continue;
            }
            if (i + 1 == sentence.length())
                return "invalid";
            else if (islower(sentence[i + 1]))
                return "invalid";
        }
    }

    규칙1과 2를 동시 검사 중
    현재 문자가 대문자인데 문자의 끝이라면 오류문자 (규칙2의 문자로 끝나야한다)

    if (i + 1 == sentence.length())
        return invalid;

    다음 문자가 대문자여도 오류문자

    else if (isupper(sentence[i + 1]))
        return invalid;

    다음 문자가 규칙1,2 문자가 아니라면 오류문자

    else if (char_rule1 != sentence[i + 1] && char_rule2 != sentence[i + 1])
        return invalid;

    다음 문자가 소문자인데 규칙1문자이면 문자 사이사이에 껴있다는 것이므로 그냥 넘어간다.
    하지만 규칙2문자이면 규칙1과 2가 끝났다는 것으로 처리하면된다.

    if (islower(sentence[i])) 
    {
        if (char_rule2 == sentence[i]) 
        {
    
            first_rule = false;
            checked[char_rule1 - 'a'] = true;
            char_rule1 = NULL;
    
            second_rule = false;
            checked[char_rule2 - 'a'] = true;
            char_rule2 = NULL;
    
            words.push_back(word);
            word = "";
    
            continue;
        }
    }

    규칙1 문자가 와서 문자가 계속 이어져야하는데, 문자열의 끝이라면 오류문자 처리한다.
    또한 다음 문자가 대문자가 아닌 소문자이면 오류처리한다. 문자열 사이에 소문자가 껴있어야하므로.

    if (i + 1 == sentence.length())
        return "invalid";
    else if (islower(sentence[i + 1]))
        return "invalid";

     

Designed by Tistory.