N Log

프로그래머스 입문 120904 숫자 찾기

문제

출처

정수 num에서 한 자리 정수 k를 찾는다.
k가 있으면 그 위치를 반환하고, 없으면 -1을 반환한다.

num k result
29183 1 3
232443 4 4
123456 7 -1
102 0 2
102 2 3

풀이

이 문제에서 주의할 점은 k의 위치가 왼쪽에서 0부터 센 인덱스가 아니라, 왼쪽에서 1부터 센 위치라는 것이다.

문자열로 바꿔 찾기

#include <stdio.h>

int solution(int num, int k)
{
    char numbers[11] = { 0 };

    sprintf(numbers, "%d", num);

    for (int i = 0; numbers[i] != '\0'; i++)
    {
        if (numbers[i] - '0' == k)
        {
            return i + 1;
        }
    }

    return -1;
}

int가 표현할 수 있는 최댓값은 2^31 - 12,147,483,647이다.
최대 10자리 숫자와 문자열의 끝을 나타내는 널 문자까지 담아야 하므로 numbers 배열의 크기를 11로 선언한다.
sprintf 함수로 int 값을 문자열로 바꾼 뒤, 앞에서부터 한 자리씩 k와 비교한다.
배열의 인덱스는 0부터 시작하지만, 문제에서 요구하는 위치는 1부터 센 값이다.
따라서 일치하는 숫자를 찾으면 i + 1을 반환한다.

앞자리부터 나눗셈으로 찾기

int solution(int num, int k)
{
    int divisor = 1;

    while (num / divisor >= 10)
    {
        divisor *= 10;
    }

    int position = 1;

    while (divisor > 0)
    {
        if (num / divisor == k)
        {
            return position;
        }

        num %= divisor;
        divisor /= 10;
        position++;
    }

    return -1;
}

앞자리부터 숫자를 가져오려면 먼저 num의 자릿수와 같은 10의 제곱을 만들고, 그 수로 num을 나누면 된다.
예를 들어 123에서 1을 가져오려면 123100으로 나누면 된다.
그래서 divisor를 10씩 곱해 num과 자릿수가 같은 값으로 만든다.

이제 divisornum의 자릿수가 같아졌다.
num / divisor로 현재 앞자리 숫자를 구하고, k와 같으면 위치를 반환한다.
앞자리 숫자를 확인했으므로 num에서 처리한 앞자리를 제거하기 위해 num %= divisor를 한다.
그다음 divisor를 10으로 나눠 다음으로 확인할 자리의 자릿값으로 바꾼다.
이 과정을 반복하다가 k를 찾으면 현재 위치를 반환하고, 끝까지 찾지 못하면 -1을 반환한다.

뒤에서부터 찾고 앞자리 위치로 바꾸기

int solution(int num, int k)
{
    int position_from_right = -1;
    int digit_count = 0;

    while (num > 0)
    {
        digit_count++;

        if (num % 10 == k)
        {
            position_from_right = digit_count;
        }

        num /= 10;
    }

    if (position_from_right == -1)
    {
        return -1;
    }

    return digit_count - position_from_right + 1;
}

앞의 “앞자리부터 나눗셈으로 찾기” 풀이에서는 앞자리부터 확인하기 위해 자릿수에 맞는 divisor를 계산해야 했다.
이 풀이에서는 그 과정을 생략하고, num % 10으로 오른쪽 끝 숫자부터 확인한다.

숫자를 하나 확인할 때마다 digit_count를 1씩 늘려 전체 자릿수를 센다.
digit_count를 증가시키는 위치는 if 문 이전이나 이후 모두 가능하다.
if 문 이후에 증가시키면 if 문이 참일 때 아직 값이 증가하지 않은 상태이므로, 오른쪽에서 0부터 센 인덱스처럼 사용할 수 있다.
반대로 if 문 이전에 digit_count를 증가시키면 오른쪽에서 1부터 센 위치처럼 사용할 수 있다.

position_from_right는 오른쪽에서 1부터 센 위치이므로, 문제에서 요구하는 왼쪽 기준 위치로 바꿔야 한다.
digit_count에서 position_from_right를 빼면 왼쪽에서 0부터 센 인덱스를 구할 수 있다.
문제에서는 왼쪽에서 1부터 세므로 + 1을 해준다.