[C언어-기초실습-6] 입력된 문자열이 회문인지 체크하시오?

in #kr-dev5 years ago (edited)

[C언어-기초실습-6] 입력된 문자열이 회문인지 체크하시오?



오늘은 회문을 체크하는 코딩을 연습하도록 하겠습니다. 회문이라는 것은 앞으로 읽으나 뒤로 읽으나 같은 단어로 구성된 문자열을 마합니다. 예로 "aba" 앞으로 읽으나 뒤로 읽으나 같은 형태를 말하는 것이죠. 이 회문을 프로그램 상 어떻게 찾아내는지 이제 알아 봅시다.

1. 문제의 이해


회문이란 앞으로 읽으나 뒤로 읽으나 문장이 같을 때 이 문자열을 회문이라고 합니다.

예로 " wow"라는 문자열을 앞으로 읽어나 뒤로 읽으나 같은 문자열입니다. 이걸 코딩을 한다면 어떻게 해야 할까요.

우선 문자열을 한글짜씩 쪼개야 합니다.

예) "wow"

이 문자열은 어디에 저장 될까요. 배열변수에 저장되겠죠.

char str[3] = "wow"

앞으로 뒤로 읽어도 같은 문자열인지 체크하기 위해서는 앞글자와 뒷글자를 서로 일치하는지 체크하면 됩니다. 그런데 체크는 언제까지 할가요. 전체 문자열을 2로 나눈 글자수 만큼 체크하면 됩니다

for(i=0;i<문자열길이/2;i++}{
    if(str[i]!=str[문자열길이-1-i]){
        printf("회문이 아니다 \n");
        break;
    }
}

문자열의 각 문자를 대칭으로 비교하는데 for문으로 표현하면 전체 문자열 길이만큼 for문을 돌릴 필요가 없습니다. 서로 앞뒤 문자를 비교를 하기 때문에 절반의 루프를 돌면 됩니다. 그래서 문자열길이/2만큼 for문 i를 돌리면 됩니다.

그리고,

if(str[i]!=str[문자열길이-1-i]){   }

i=0일 때 str[i]는str[문자열길이-1-i] 표현은 앞첫글자 str[0]와 뒷첫글자 str[문자열길이-1-0]을 비교합니다. i가 1씩 증가할 때마다 앞 두번째글자와 뒷 두번째 글자를 비교합니다. 그런데 문자열길이는 NULL 문자열 포함한 문자열 길이의 수를 나타내는데 문자열은 주소지 0번째 부터 이기에 3글자이면 strlen(str)의 값은 3이 반환 됩니다. 마지막 글자의 위치는 문자열길이 -1을 해야 해당 위치를 가리키기 때문에 "문자열길이-1-i"라 표현합니다.

    str_L=strlen(inputStr);
    for(i=0;i<str_L/2;i++){
        if(inputStr[i]!=inputStr[str_L-1-i]){
            printf("회문이 아니다!\n");
            break;
        }
    }

배열변수 선언과 문자열 입력


char inputStr[10];

printf("문자열을 입력하시오? ");
scanf("%s",inputStr);   

scanf()함수로 서식문자 "%s"을 이용하여 inputStr배열번지에 문자열을 저장하게 됩니다.

참고로 다음 함수로도 표현이 가능합니다.

gets(inputStr);

표현은 여러분들의 자유 입니다.

포인트 배열변수 선언과 문자열 입력


포인트 배열변수를 선언하여 문자열을 입력 받을 수도 있습니다.

char *inputStr = malloc(sizeof(char) * 10);    

printf("문자열을 입력하시오? ");
scanf("%s",inputStr);   
//gets(inputStr);

문자열 길이


#include <stdlib.h>

int str_L;
str_L=strlen(inputStr);

2. 코딩


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>

int main(int argc, char *argv[]) {
    
    char inputStr[10];
    //char *inputStr = malloc(sizeof(char) * 10);    
    int i;
    int str_L;
    
    printf("문자열을 입력하시오? ");
    scanf("%s",inputStr);   
   //gets(inputStr);
    
    str_L=strlen(inputStr);
    for(i=0;i<str_L/2;i++){
        if(inputStr[i]!=inputStr[str_L-1-i]){
            printf("회문이 아니다! =>");
            break;
        }
    }
    
    printf("%s \n",inputStr);       
    
    system("pause");
    return 0;
}

참고로,

printf("%s \n",inputStr);       

이 표현을 쪼개서 한글짜식 출력 한다면 다음과 같습니다.

for(i=0;i<str_L;i++){
    printf("%c",inputStr[i]);       
}
printf("\n");

표현이 다양하죠.

[결과]
a1.jpg

3. 사용자 정의 함수로 main()함수 코딩을 간단화


[전체소스]

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <Windows.h>

int Palindrome(char *str){
    int i;
    int str_L;
    int state=1;
    
    str_L=strlen(str);  
    for(i=0;i<str_L/2;i++){
        if(str[i]!=str[str_L-1-i]){
            state=0;
            break;
        }
    }
    return state;   
}

int main(int argc, char *argv[]) {
    
    char inputStr[10];  
    int i; 
    int chk;
    
    printf("문자열을 입력하시오? ");
    scanf("%s",inputStr);   
    
    chk=Palindrome(inputStr); //회문 체크 
    
    if(chk==1) printf("%s은 회문이다.\n",inputStr);
    else printf("%s은 회문이 아니다.\n",inputStr);     
    
    system("pause");
    return 0;
}

위 소스를 보시면 회문을 찾는 처리문을 전부 사용자 정의 함수로 만들어서 코딩을 옮겼습니다. 그래서 main()함수를 보시면 최소화 된 코딩으로 보기가 편해졌습니다. main()함수 내 코딩을 보면 뭘 코딩 한지 가독성이 높아졌을 거에요. 이렇게 특정 알고리즘을 따로 사용자 정의 함수로 표현하면 단지 main()함수 내에서는 함수명만 코딩해서 그 의미를 쉽게 알아볼 수 있습니다.

[결과]
a2.jpg

마무리


오늘은 회문을 구하는 코딩을 해보았는데 같은 표현의 코딩을 좀 다르게 코딩하는 법을 다뤘네요. 그리고 회문 알고리즘을 사용자 정의 함수로 외부로 빼내 main()함수 코딩을 최소화 시켜보았습니다. 여기서 사용자 정의 함수로 표현한 회문 알고리즘을 재귀함수로 표현이 가능한데 그 부분은 일부러 여러분들이 지난 시간에 연습한 실습 재귀함수 코딩을 한 실습 약수와 소수 구하는 실습 두편의 내용을 잘 읽고 원리를 이해하셔서 오늘 회문 구하는 원리를 재귀함수로 수정하시면 됩니다. 재귀함수의 원리를 이용한다면 딱하나 문자열을 비교할 때 일치하면 다시 자기 자신함수를 재호출하여 다음 글자를 비교하는 식으로 재귀함수를 표현 하면 됩니다. 약수와 소수 구하는 코딩에서 살펴본 재귀함수의 원리를 이해하시면 충분히 이 실습 내용도 재귀함수로 표현이 가능 할 거라 생각 됩니다.

한번 도전해 보세요.


Sponsored ( Powered by dclick )

dclick-imagead

Coin Marketplace

STEEM 0.28
TRX 0.11
JST 0.031
BTC 68846.60
ETH 3872.96
USDT 1.00
SBD 3.66