ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 21. 자릿수 더하기
    코딩 테스트/Level 1 2019. 10. 19. 23:35
    반응형

    https://programmers.co.kr/learn/courses/30/lessons/12931

     

    파이썬

    가장 정석적인 풀이를 보겠습니다. 

    10으로 나눠서 나머지를 추려내는 방식으로 각 자릿수를 분리합니다. 

    def solution(x): 
        total = 0 
        while x != 0: 
            total += x % 10 
            x = x // 10 
        return total

    그런데 %도 나누기 //도 나누기입니다. 나누기를 1번만 할 수는 없을까요?
    내장 함수(BIF) 중 divmod 함수를 이용하면 됩니다.
    https://wikidocs.net/32#divmod
    (다만 divmod이 나누기를 두 번 하는 것보다 항상 빠른 게 아닙니다. 작은 수에선 더 느림 ㅠ,.ㅠ)
    https://stackoverflow.com/questions/30079879/is-divmod-faster-than-using-the-and-operators

    def solution(x):
        total = 0
        while x: # x != 0
            x, y = divmod(x, 10)
            total += y
        return total

    문자열로 형변환을 해서 푸는 방법도 있습니다. 

    def solution(x):
        total = 0
        for each in str(x):
            total += int(each)
        return total

    for문은 리스트 컴프리헨션(list comprehension)으로 줄여 쓸 수 있습니다. 

    def solution(x):
        return sum([int(each) for each in str(x)])

    제너레이터 표현식(generator expression)이 더 좋습니다. 

    def solution(x):
        return sum(int(each) for each in str(x))

    map을 사용해도 되죠. 

    def solution(x):
        return sum(map(int, str(x)))

     

    자바스크립트

    파이썬에 리스트 컴프리헨션이 있다면, 다른 현대 언어들에는 함수형 프로그래밍이 있습니다. 

    function solution(x) {
        return String(x).split('').map(Number).reduce((a, b) => a + b)
    }

     

    자바

    고전적인 느낌으로 원시자료형인 char (캐릭터, 글자) 형을 이용해 봤습니다. 

    char를 쓰면 C언어를 독학하던 고등학교 때가 떠오릅니다.

    숫자를 문자열 -> 캐릭터형 배열로 변환합니다.
    캐릭터형 = 아스키코드(요즘은 유니코드 던가??)입니다.
    즉 아스키코드가 들어간 배열로 변하는 거죠.
    아스키코드표를 보면 숫자 '0' 은 아스키코드 48이고, 또 이것이 순서대로 나열되어 있습니다.
    여기서 48을 빼주면 원래 숫자로 바뀌겠죠?
    48을 외울 필요도 없습니다. '0' = 48 이겠죠.
    https://namu.wiki/w/%EC%95%84%EC%8A%A4%ED%82%A4%20%EC%BD%94%EB%93%9C
    https://wikidocs.net/261

    class Solution {
        public int solution(int x) {
            int sum = 0;
            for (char num: String.valueOf(x).toCharArray()) 
            	sum += (num -'0');
            return sum;
        }
    }

    한 줄로

    class Solution {
        public int solution(int x) {
            return String.valueOf(x).chars().map(num -> num - '0').sum();
        }
    }

     

    코틀린

    자바에서 사용한 char를 함수형으로 작성해 보았습니다.

    코틀린에서는 '0' 뒤에 .toInt()를 붙여줘야 합니다. 

    class Solution {
        fun solution(x: Int): Int {
            return x.toString().chars().map { it - '0'.toInt() }.sum()
        }
    }

     

    고는 현대적인 씨 언어입니다.
    씨와 파이썬 사이의 어디쯤인 느낌이랄까요?
    코틀린과도 비슷한 구문이 있습니다.
    함수형은 안되지만.. 

     

    정석적인 방법입니다. 

    func solution(n int) int {
    	answer := 0
    	for n > 0 {
    		answer += n % 10
    		n /= 10
    	}
    	return answer
    }

     

    (고 언어답지 않은 방식이지만 연습을 위해서)
    문자열을 이용해 보겠습니다. 

     

    string()을 이용해 정수를 문자열로 변환할 때,
    string() 함수는 정수 값을 유니코드 값으로 해석합니다.
    즉, string(97) == 'a'가 됩니다.
    우리가 기대했던 것은 "97"인데 말이죠. 

    package main
    
    func main() {
    	print(string(97))  // a
    }

    우리가 원하는 "97"을 얻기 위해서는 문자열 변환 함수인 strconv.Itoa(n)을 사용해야 합니다. 

    라이브러리를 불러야하고, 코드가 길어지고..
    ㅇㅇ 굳이 이렇게 코딩할 이유가 없습니다. 

    package main
    
    import "strconv"
    
    func solution(n int) int {
    	answer := 0
    	for _, v := range strconv.Itoa(n) {
    		answer += int(v - '0')
    	}
    	return answer
    }
    
    func main() {
    	println(solution(123))
    }

    C#

    public class Solution
    {
        public int solution(int n)
        {
            int sum = 0;
            foreach (char num in n.ToString().ToCharArray())
                sum += num - '0';
            return sum;
        }
    }
    

    한 줄로

    using System.Linq;
    
    public class Solution
    {
        public int solution(int n) =>
            n.ToString().ToCharArray().Aggregate(0, (a, b) => a + b - '0');
    }
    반응형
Designed by Tistory.