URI 문제

  • lovetop
    lovetop

    해당문제 : URI
    C++을 공부하려고 튜토리얼을 첨부터 풀어보고 있습니다.
    C 스런 코드를 짜긴 했지만 동작은 정상일 거 같은데 혹시 아래 코드로 돌렸을 때 어떤 에러 케이스에 대한 문제가 있을까요..?

    • 주어진 %코드 외에는 치환 안함
    • 1~100 외에 다른 값에 대한 예외처리

    정도 예외처리 했는데 다른 경우를 더 고려해야할게 있을까요?

    #include<iostream>
    
    using namespace std;
    
    int main(int argc, char** argv)
    {
        int T;
    
        cin >> T;
    
        if (T < 1 || T > 100)
            return 0;
    
        while (T-- > 0)
        {
            int i=0;
            char C[82] = { '\0', };
    
            cin >> C;
    
            while (C[i] != '\0') {
                if (C[i] == '%' && C[i+1] == '2')
                {
                    bool check = true;
    
                    switch (C[i+2])
                    {
                    case '0':
                        C[i] = ' ';     break;
                    case '1':
                        C[i] = '!';     break;
                    case '4':
                        C[i] = '$';     break;
                    case '5':
                        C[i] = '%';     break;
                    case '8':
                        C[i] = '(';     break;
                    case '9':
                        C[i] = ')';     break;
                    case 'a':
                        C[i] = '*';     break;
                    default:
                        check = false;  break;
                    }
    
                    if (check)
                    {
                        int j = i + 1;
                        while (C[j] != '\0') C[j++] = C[j + 2];
                        C[j] = '\0';
                    }
                }
                i++;
            }
            cout << C << endl;
        }
    
        return 0;
    }
    

    7년 전
2개의 댓글이 있습니다.
  • keith
    keith

    아무도 답변을 아직 안달아주셔서 도움이 될까 적어봅니다.
    직접 돌려보진 않고 눈으로만 본거라, 제가 틀릴 수도 있어요^^;

    돌아가는거 자체는 큰 문제가 없어보입니다.
    하지만 개선할 수 있는 몇가지 포인트가 있어서 적어봅니다.
    문제가 되는 부분은 아래 부분입니다.
    해당부분을 치환하고 나서 문자열을 땡겨주시는거 같은데요..

    if (check)
    {
        int j = i + 1;
        while (C[j] != '\0') C[j++] = C[j + 2];
        C[j] = '\0';
    }
    

    위의 소스를 아래처럼 바꿔주시는게 이론상은 맞는 이야기입니다. (뭐 굳이 안바꾸셔도 상관없습니다.)

    if (check)
    {
        int j = i + 1;
        while (C[j + 2] != '\0') C[j++] = C[j + 2];
        C[j] = '\0';
    }
    

    하지만, 제 생각에는 이러한 방법은 비효율적인것 같습니다.

    왜냐하면 해당 인코딩 부분을 바꿀때마다 문자열을 당겨주고 있는데, 이렇게 하지 말고, 나중에 한꺼번에 당겨주는건 어떤가요?
    굳이 소스를 적진 않고, 방법만 설명 드리면,
    1. 문자열의 길이를 계산하여 저장해둠
    2. %2? 로 되어있는 부분의 첫번째를 해당하는 문자로 치환하고 나머지를 \0으로 변경해둠
    3. 마지막에 루프를 돌면서, 한꺼번에 문자열을 당겨줌

    // 만약 n이 문자열의 길이라고 할때,
    for(int i = 0, int t = 0; i + t < n; i++) {
        if(C[i+t] == '\0') {
            t += 2;
        }
        C[i] = C[i+t];
    }
    

    이렇게 마지막에 한방에 처리할 수 있습니다. (소스 검증은 못하겠음^^)


    7년 전 link
  • lovetop
    lovetop

    이 코드는 버리고 다시짜기를 십여회 반복해서 패스하긴했습니다.
    근데 왜 되는것과 안되는것의 차이를 모르겠습니다...
    좀 더 공부하고 다시 풀어봐야 할듯합니다 ㅠㅠ

    아 그리고 추가로 확인한건 문제에서 절대 넘지 않는 범위에 대해서 중복으로 예외처리를 하게되면 그것은 오류로 인식하더군요.....
    마지막에 패스한 코드와 이전 코드의 차이는 예외처리 유무였습니다;;;


    7년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.