본문 바로가기

Education

[부스트 코딩 뉴비 챌린지 2020] week4_미션01 애너그램(anagram)

반응형
#include <stdio.h>
#include <string.h>
#define MAX 256

void test_anagram(const char* s1, const char* s2);
int is_anagram(const char* s1, const char* s2);

int main(void){
    test_anagram("silent","listen");
    test_anagram("garden","ranged");
    test_anagram("split","lisp");

    return 0;
}

void test_anagram(const char* s1, const char* s2){
    if(is_anagram(s1,s2)){  //return 1;
        printf("%s %s : anagram\n", s1, s2);
    }else{  //return 0;
        printf("%s %s : not anagram\n",s1, s2);
    }
}

int is_anagram(const char* s1, const char* s2){
    int i, j;
    int check;

    if(strlen(s1) != strlen(s2)){
        return 0; 
    }

    char buf[MAX] = ""; 
    strcpy(buf, s1);

    for(i = 0; s2[i]; i++){ 
        check = 0; 
        for(j = 0; buf[j]; j++){   
            if(s2[i] == buf[j]){
                strcpy(buf+j, buf+j+1); 
                check = 1; 
                break;  
            }
        }
        if(check == 0){
            return 0;  
        }
    }
    return 1; 
}

 

 

이해를 돕는 설명 코드

#include <stdio.h>
#include <string.h> //strneln(), strcpy_s(char *dest, int dest_size(dest가 가리키는 메모리의 크기), const char *src);
#define MAX 256

void test_anagram(const char* s1, const char* s2);
int is_anagram(const char* s1, const char* s2);

int main(void){
    test_anagram("silent","listen");
    test_anagram("garden","ranged");
    test_anagram("split","lisp");
    test_anagram("ssss","sssw");
    test_anagram("aaff","afff");
    test_anagram("afff","aaff");

    return 0;
}

void test_anagram(const char* s1, const char* s2){
    if(is_anagram(s1,s2)){  //return 1;
        printf("%s %s : anagram\n", s1, s2);
    }else{  //return 0;
        printf("%s %s : not anagram\n",s1, s2);
    }
}

int is_anagram(const char* s1, const char* s2){
    int i, j;
    int check;

    if(strlen(s1) != strlen(s2)){
        return 0;   //anagram (X)
    }

    char buf[MAX] = ""; //s1을 복사하는 문자열
    strcpy(buf, s1);

    for(i = 0; s2[i]; i++){ //s2[i]가 종료문자. 즉, 거짓이면 종료
        check = 0;  //check=0(거짓)으로 초기화 (s2[i]에 종료문자 없음)
        for(j = 0; buf[j]; j++){    //buf[j]가 종료문자. 즉, 거짓이면 종료
            if(s2[i] == buf[j]){
                printf("buf+j: %c\n",buf+j);
                printf("buf+j+1: %c\n",buf+j+1);
                strcpy(buf+j, buf+j+1); //buf+j를 buf+j+1로 변경 (문자열 buf에서 buf+j이후 부분이 buf+j+1로 변경되므로 j번째 문자가 제거됨)
                printf("%s\n", buf);
                check = 1;  // 같으면 check=1
                break;
            }
            printf("%s\n", buf);
        }
        if(check == 0){
            return 0;   //anagram (X)
        }
    }
    return 1;   //anagram (O)
}
<예시 1>
silent
silent
buf+j: l
buf+j+1: e
sient
sient
buf+j: i
buf+j+1: e
sent
buf+j: s
buf+j+1: e
ent
ent
ent
buf+j: t
buf+j+1:
en
buf+j: e
buf+j+1: n
n
buf+j: n
buf+j+1:

silent listen : anagram

<예시 2>
garden
garden
buf+j: r
buf+j+1: d
gaden
gaden
buf+j: a
buf+j+1: d
gden
gden
gden
gden
buf+j: n
buf+j+1:
gde
buf+j: g
buf+j+1: d
de
de buf+j: e
buf+j+1: d
buf+j: d
buf+j+1:

garden ranged : anagram

<예시 3>
split lisp : not anagram (문자열 길이가 다르므로 비교할 필요도 없음)

<예시 4>
buf+j: s
buf+j+1: s
sss
buf+j: s
buf+j+1: s
ss
buf+j: s
buf+j+1: s
s
s

ssss sssw : not anagram


<예시 5>
buf+j: a
buf+j+1: a
aff
aff
buf+j: f
buf+j+1: f
af
af
buf+j: f
buf+j+1: a
a

aaff afff : not anagram

<예시 6>
buf+j: a
buf+j+1: f
fff
fff
fff
fff

afff aaff : not anagram

size2[i] = buf[j]일 때마다 해당 buf[j]의 값을 삭제한다. 그리고 int check값을 변수로 두어 두 값이 다를 경우 0, 같으면 1로 변경한다.
그렇게 buf의 값을 하나씩 없애면서, size2의 i가 for문의 끝까지 돌았을 때 check가 1이면 애너그램, 0이면 애너그램이 아니다.

여기서 buf를 만들지 않고 size1을 바로 사용해도 되긴하지만, 마지막에 두 값과 함께 애너그램 유무 여부를 출력하므로 원본값은 훼손하지 않기 위해 따로 buf 배열을 생성하는 편이 좋다.



 

 

[C언어 소스] 애너그램(anagram) 문자열 판별하기 – 언제나 휴일

안녕하세요. 언제나 휴일입니다. 이번에는 두 개의 문자열이 애너그램(anagram) 인지 판별하는 소스 코드입니다. 애너그램이란 서로 다른 문자열을 구성하는 문자의 집합이 같은 것을 말합니다. ��

ehpub.co.kr

반응형