-
[프로그래머스 2단계] 알고리즘 23. 하샤드수 구하기24년 11월 이전/레거시-알고리즘(3) 2018. 4. 9. 11:09반응형
문제 출처는 프로그래머스 알고리즘 연습 에서 볼 수 있습니다!(https://programmers.co.kr/learn/challenges)
알고리즘 23. 하샤드수 구하기
양의 정수 x가 하샤드 수이려면 x의 자릿수의 합으로 x가 나누어져야 합니다. 예를들어 18의 자릿수 합은 1+8=9이고, 18은 9로 나누어 떨어지므로 18은 하샤드 수입니다.Harshad함수는 양의 정수 n을 매개변수로 입력받습니다. 이 n이 하샤드수인지 아닌지 판단하는 함수를 완성하세요. 예를들어 n이 10, 12, 18이면 True를 리턴 11, 13이면 False를 리턴하면 됩니다.
public class HarshadNumber{public boolean isHarshad(int num){return true;}// 아래는 테스트로 출력해 보기 위한 코드입니다.public static void main(String[] args){HarshadNumber sn = new HarshadNumber();System.out.println(sn.isHarshad(18));}}풀이 :
문제의 핵심은 입력 받은 숫자의 자릿수들의 합을 어떻게 구하느냐이다. 이 문제는 알고리즘 22번의 알고리즘과 유사하다. 알고리즘 22는 입력받은 숫자를 자릿수들의 문자열 리스트로 바꾸고 정렬한 후 원래 자릿수로 찾아가기 위해 차례 차례 곱하고 더해주는 연산을 했었다. 이번에는 입력 받은 숫자의 자릿수들의 문자열 리스트로 만든 후 합쳐준 후 그 숫자와 입력받은 숫자가 나누어 떨어지는지 체크하기만 하면 된다. 간단하게 내 알고리즘을 나타내면 다음과 같다.
- 입력 받은 숫자가 하샤드 수인지 판단하기 위한 각 자릿수를 합친 숫자 factor를 만든다.
- 입력 받은 수를 자릿수들의 문자열 리스트로 만든다. -> Arrays.asList(Integer.toString(num).split(""))
- 문자열 리스트를 스트림으로 만든다. -> stream()
- 스트림 요소들을 문자열에서 정수형으로 바꾼다. -> map(Integer::parseInt)
- 이들을 합쳐준다. -> reduce(0, (a, b) -> a+b)
- 그 요소를 구했으면 입력받은 숫자와 나누어 떨어지는지 검사한다. -> num % factor == 0
내 코드는 다음과 같다.
public boolean isHarshad(int num){int factor = Arrays.asList(Integer.toString(num).split("")) //1-1.stream() //1-2.map(Integer::parseInt) //1-3.reduce(0, (a, b) -> a + b); //1-4return num % factor == 0; //2}reduce를 쓰기 싫다면 IntStream으로 바꿔서 만들면 된다. Stream<Integer>에서 IntStream은 mapToInt()를 활용하여 바꿀 수 있다. 코드는 다음과 같다.
public boolean isHarshad(int num){int factor = Arrays.asList(Integer.toString(num).split("")).stream().map(Integer::parseInt).mapToInt(Integer::intValue) //Stream<Integer> -> IntStream.sum();return num % factor == 0;}나 같은 경우는 굳이 sum()을 위해서 스트림을 한번 더 매핑하는 것보다 reduce 연산을 쓰는 것이 더 좋아한다. 왜냐하면 싱글 코어 환경에서 스트림 연산은 잘 짜여진 일반 연산보다는 느린 편이다. 굳이 스트림 연산을 늘리는 것은 속도가 더 낮아질 확률이 있다. 어떤 사람들은 그렇다면 잘 짜여진 코드가 빠르다면 굳이 왜 써?라고 반문할 수도 있는데 멀티 코어 환경 여러 스레드가 접근해서 연산할때 차이가 분명하다. 일반 연산은 멀티스레드 환경에서 불안전하기 때문에 안전 코드를 삽입해야 하지만 스트림 연산은 stream() 뒤에 parallel() 을 호출하기만 하면 연산을 덧붙일 필요 없이 병렬 환경에서 안전한 연산을 수행할 수 있다. 그리고 일반 스트림 연산보다 약간 늦을 뿐 연산 속도 차이에는 크게 차이가 없다. 이것이 스트림 연산, 자바의 함수형 프로그래밍의 최대 장점이다.
728x90'레거시 > 레거시-알고리즘(3)' 카테고리의 다른 글
[프로그래머스 2단계] 알고리즘 25. 이상한 문자 만들기 (0) 2018.04.11 [프로그래머스 2단계] 알고리즘 24. 행렬의 곱셈 (0) 2018.04.10 [프로그래머스 2단계] 알고리즘 22. 정수 내림차순으로 배치하기 (0) 2018.04.06 [프로그래머스 2단계] 알고리즘 21. 괄호 확인하기 (0) 2018.04.06 [프로그래머스 2단계] 알고리즘 20. 자연수를 뒤집어 리스트로 만들기 (0) 2018.04.05