본문 바로가기
Algorithm/Algorithm

특정 진법 정수로 바꾸기

by OdOp 관리자 2023. 12. 5.
SMALL

특정 입력받은 문자열을 정수형으로 변환하는 방법을 알아보도록 하겠습니다. 

포스팅을 읽기 전에 이전에 포스팅했던 atoi에 대해 아직 보지 못하신 분은 한번 참고해 주시길 바라겠습니다. 

https://hig0617.tistory.com/100

 

만약에 문자열에 공백들이 있으면 이를 제거해 주어야 합니다.

부호가 여러개가 있으면 '-'가 홀수이면 음수로 짝수이면 양수로 부호를 정해 주어야 합니다.  

저희는 위의 역할을 해주는 함수를 OdOp_sign이라 정하겠습니다. 

 

 

OdOp_sign

char* OdOp_sign(int* sign, char* str)
{
    while (*str == 32 || (*str >= 9 && *str <= 13))
    {
        str++;
    }
    while (1)
    {
        if (*str == '-')
            *sign *= -1;
        else if (*str != '+')
            break;
        str++;
    }
    return (str);
}

이부분의 자세한 설명은 이전 포스팅(https://hig0617.tistory.com/100) 잘 나와있습니다. 

 

다음으로 바꿀 진법의 인자의 형태가 적절한 형태인지와 몇 진법인지 파악해야 합니다. 

이게 무슨 말인지 아래에서 하나하나 설명해 드리겠습니다. 

저희는 위의 역할을 해주는 함수를 OdOp_base이라 정하겠습니다. 

 

 

OdOp_base

int    OdOp_base(char *base)
{
    int    n;
    int    i;

    n = 0;
    while (base[n] != '\0')
    {
        i = 0;
        if (base[n] == '+' || base[n] == '-')
            return (0);
        else if (base[n] == 32 || (base[n] >= 9 && base[n] <= 13))
            return (0);
        while (base[i] != '\0')
        {
            if (base[i] == base[n] && i != n)
                return (0);
            i++;
        }
        n++;
    }
    return (n);
}

진법 인자인 base 문자열에 부호가 있으면 부호를 표시할 수 없기 때문에 0을 리턴하게 했습니다. 

공백이 포함되어 있으면 tab과 구분을 할 수 없을 수 있기 때문에 역시 0을 리턴하게 했습니다. 

마지막으로 같은 것이 반복이 되면 0을 리턴하게 했습니다. 

 

모든 부분을 만족한다면 문자열의 길이를 리턴하여 몇 진법인지 파악하게 했습니다. 

 

다음으로 진법의 형태를 파악했으니 정수형으로 바꾸도록 하겠습니다. 

 

 

OdOp_answer

int    OdOp_answer(int n, char *str, char *base)
{
    int    i;
    int    answer;

    answer = 0;
    while (*str != '\0')
    {
        i = 0;
        while (*str != base[i] && base[i] != '\0')
        {
            i++;
        }
        if (base[i] != '\0')
        {
            answer *= n;
            answer += i;
        }
        else
            break ;
        str++;
    }
    return (answer);
}

str에 저장된 문자가 base에 저장이 되어있다면 정수형으로 계산해 줍니다. 

str문자가 끝나거나 더이상 base에 저장이 되어있지 않다면 현재까지 변환한 정수를 리턴해 줍니다. 

 

이제 위의 함수를 합쳐봅시다. 

 

 

OdOp_atoi_base

int    OdOp_atoi_base(char *str, char *base)
{
    int    answer;
    int    sign;
    int    n;

    sign = 1;
    str = OdOp_sign(&sign, str);
    n = OdOp_base(base);
    if (n < 2)
    {
        return (0);
    }
    answer = OdOp_answer(n, str, base);
    return (answer * sign);
}

여기서 특이한 부분은 n이 2미만일 경우에는 0을 리턴하게 했습니다. 

진법이 1이거나 0이면 가능하지 않기 때문에 정수를 리턴할 수 없습니다. 

 

 

예시를 한번 살펴보겠습니다. 

#include <stdio.h>

char* OdOp_sign(int* sign, char* str)
{
    while (*str == 32 || (*str >= 9 && *str <= 13))
    {
        str++;
    }
    while (1)
    {
        if (*str == '-')
            *sign *= -1;
        else if (*str != '+')
            break;
        str++;
    }
    return (str);
}

int    OdOp_base(char *base)
{
    int    n;
    int    i;

    n = 0;
    while (base[n] != '\0')
    {
        i = 0;
        if (base[n] == '+' || base[n] == '-')
            return (0);
        else if (base[n] == 32 || (base[n] >= 9 && base[n] <= 13))
            return (0);
        while (base[i] != '\0')
        {
            if (base[i] == base[n] && i != n)
                return (0);
            i++;
        }
        n++;
    }
    return (n);
}

int    OdOp_answer(int n, char *str, char *base)
{
    int    i;
    int    answer;

    answer = 0;
    while (*str != '\0')
    {
        i = 0;
        while (*str != base[i] && base[i] != '\0')
        {
            i++;
        }
        if (base[i] != '\0')
        {
            answer *= n;
            answer += i;
        }
        else
            break ;
        str++;
    }
    return (answer);
}

int    OdOp_atoi_base(char *str, char *base)
{
    int    answer;
    int    sign;
    int    n;

    sign = 1;
    str = OdOp_sign(&sign, str);
    n = OdOp_base(base);
    if (n < 2)
    {
        return (0);
    }
    answer = OdOp_answer(n, str, base);
    return (answer * sign);
}

int main(void)
{
    char test7[] = "   -+-+---235Hsa";
    char *base1 = "0123456789ABCDEF";

    printf("str : '   -+-+---235Hsa' | base : 0123456789ABCDEF\n");
    printf("answer : -565 | your result : %d\n", OdOp_atoi_base(test7, base1));
    return (0);
}
LIST