121

코딩 도장

일주일에 하나씩 가벼운 마음으로 코드를 작성합니다. 누가 떠밀지 않아도 스스로 자라길 원하는 사람들...
클럽장: 아샬 | http://club.filltong.net/codingdojo
최근 방문자들   모든회원보기
풀이 풀이
Letter Bank (C++)  

2008. 06. 21 01:17   |   조회수:117
CoMKiD CoMKiD
http://club.filltong.net/codingdojo/4222  복사

이번 주는 불타오르는군요!!

원래 C로 짜도 되지만.. 코드 읽기 좋으라고 C++로 짰어요.

bitmask를 이용하니 별다른 문자열 처리 없이도 간단하게 되네요. :)

(뭐 다른 언어를 사용하신 분들에 비하면 여전히 긴..)

 

입력에 대해서는 대소문자는 구분하지 않았구요.

대문자든 소문자든 첫번째 입력이 두번째 입력에 모두 포함되면 YES 처리 했어요.

이번엔 assert를 이용해서 test case도 넣었습니다~

 

  1. #include <iostream>
    #include <cassert>
    using namespace std;

    #define MASK( c )    ( 0x1 << (int) ( toupper( (c) ) - 'A' ))

    class Bank
    {
        public :
            Bank( const char * str ) : table( 0 )
            {
                while ( *str )
                    table |= MASK( *str++ );
            }

            bool includes( const char * sub ) const
            {
                while( *sub && ! ( table & MASK( *sub++ ) ) )
                    return false;
                return true;
            }
        private :
            int table;

            friend void testBank();
    };

    void testBank()
    {
        Bank b( "abc" );
        assert( b.table == ( 0x1 | 0x2 | 0x4 ) );
        assert( b.includes( "bc" ) == true );
        assert( b.includes( "d" ) == false );

        Bank s1( "MISSISSIPPI" );
        assert( s1.includes( "IMPS" ) == true );
        Bank s2( "Blue" );
        assert( s2.includes( "BLUE" ) == true );
        Bank s3( "COCONUT" );
        assert( s3.includes( "CunT" ) == true );
        Bank s4( "PC" );
        assert( s4.includes( "ipc" ) == false );
    }

    int main( int argc, char * argv[] )
    {
    #ifdef __TEST__
        testBank();
    #else
        if ( argc == 3 )
        {
            Bank b( argv[2] );
            cout << ( b.includes( argv[1]) ? "YES" : "NO" ) << endl;
        }
    #endif
        return 0;
    }

 

댓글 6

  • 원래 처음에 이 문제 딱 보고는 STL 의 집합연산 알고리즘(includes)을 이용해볼까 했었는데 이 경우에는 데이터가 정렬되어 있어야 하고 문자열의 경우에는 STL 컨테이너로 변환하는 작업까지 거쳐야 해서 귀찮더군요. 귀찮은 덕분에 더 쉬운 방법을 찾은.. 2008. 06. 21 01:23
  • 흐윽, 죄송함댜. 문제 고쳐서 올렸어요. ;ㅁ; 2008. 06. 21 04:45
  • 수정된 경우라면 그냥 두 문자열의 알파벳 mask table이 일치하면 되겠네요. C로 간단하게 해보면..

    unsigned int getMask( const char * str )
    {
    unsigned int mask = 0;
    while( *str ) mask |= MASK( *str++ );
    return mask;
    }

    int isLetterBank( const char * s1, const char * s2 )
    {
    return ( getMask( s1 ) == getMask( s2 ) );
    }

    // ...
    printf( "%s\n", (isLetterBank( argv[1], argv[2]) ? "YES" : "NO") );
    2008. 06. 21 09:50
  • 만약 16비트 환경에서 이 프로그램을 작동시키면 어떻게 될까요?

    물론, 그런 환경이 요새는 잘 없겠지만요... -_-;;;;;;;;;;;
    2008. 06. 23 09:44
  • 좋은 지적이시네요.. ㅎㅎ 그 부분은 다시 고민 해보죠~ 2008. 06. 23 13:09
  • 점심시간에 잠시 짬을 내서.. int 대신 char 배열을 사용하도록 수정해봤습니다..

    void setMask( char c, char * pTbl )
    {
    c = toupper( c ) - 'A';
    pTbl[ c / 8 ] |= ( 0x1 << ( c % 8 ) );
    }

    void setLetterTable( const char * s, char * pTbl )
    {
    while( *s ) setMask( *s++, pTbl );
    }

    int isLetterBank( const char * s1, const char * s2 )
    {
    unsigned char tbl1[4] = { 0 };
    unsigned char tbl2[4] = { 0 };

    setLetterTable( s1, tbl1 );
    setLetterTable( s2, tbl2 );

    return ( strcmp( tbl1, tbl2 ) == 0 );
    }
    2008. 06. 23 13:37
등록
목록 맨뒤로 글쓰기
다음글다음글   LetterBank (파이썬)   |   
이전글이전글   Letter bank(python)   |