알고리즘을 어떻게 공부할지 몰라 일단은 코딩테스트 연습을 하면서 익히고 있다.
프로그래머스 1단계 ing
Stream vs ArrayList, for문
- stream을 사용했을 때, 코드의 가독성, 유지보수성은 좋아보인다. 하지만, 문제를 풀다보면 그냥 ArrayList 가지고 for문 로직으로 했을 때보다 속도가 많이 느리기도 했다.
Stream
- Stream은 데이터의 필터링, 매핑, 변환 등을 수행하기 위한 함수형 프로그래밍 API
- ArrayList보다 유리한 경우
- 대용량 데이터를 병렬 처리할 때 훨씬 빠를 수 있다. ex) parallelStream()
- 다양한 필터링 및 변환 작업
- Stream API는 필터링, 매핑, 변환 등 복잡한 작업을 함수형 스타일로 간결하게 표현할 수 있으며, JVM이 최적화할 수 있는 기회를 제공
- 코드의 가독성과 유지보수성
ArrayList
- ArrayList는 데이터를 저장하고 수정하는 데 사용되는 컬렉션 클래스
- Stream보다 유리한 경우
- 단순 반복 및 액세스 작업
- 오버헤드가 적은 경우
- Stream은 중간 연산 (map, filter 등)과 종단 연산 (forEach, reduce 등)을 필요로 하는데, 이러한 과정에서 추가적인 오버헤드가 발생할 수 있습니다.
- 반면에 ArrayList는 별도의 중간 연산 없이 데이터를 다룰 수 있으므로 오버헤드가 적습니다.
- 간단한 처리 작업
직접 알고리즘으로 푸는 것과 이미 구현된 함수로 푸는 것 중 무엇이 나을까?
조심해야할 에러
- Exception in thread "main" java.util.ConcurrentModificationException
- for문에 쓰이는 arrayList에 새롭게 add하려고 하기에
- NumberFormatException
- 주어진 n이 너무 크면 int의 범위를 벗어난다 => long 타입 활용
문제 풀면서 발견한 공식?
- 홀수와 짝수의 구분: x % 2 == 0
- 숫자로만 이루어졌는지 확인
- Double.parseDouble(), Integer.parseInt(s) 메소드 try-catch
- str.matches("[+-]?\d(\.\d+)?"), s.matches("(^[0-9]$)")
- str.chars().allMatch(Character::isDigit)
- 소수 찾기:
- 약수 구하기: 제곱근까지 % i == 0 인 것들을 모으고, 나머지 뒷부분인 n / x 들을 더해준다.
- 숫자의 각 자리 구하기: n % 10 을 해서 나머지를 구하고, n = n / 10
- char를 활용하여 숫자 문자열 -> 숫자 : char - 48 ex) "0" -> 0
- 제곱인지 아닌지 : Math.sqrt(n)가 double타입인데, if(Math.sqrt(n)%1 ==0) ⇒ 완벽한 제곱근
지향점
- 변수를 할당하는데, 1번만 사용된다면 할당하지않고 사용해보자.
- 속도: 불필요한 변환 제거
알아두면 좋은 함수, 클래스
- 날짜: LocalDate, DayOfWeek
- 숫자: 제곱근(Math.sqrt), 제곱(Math.pow), 대소비교(Math.min)
- Char
- 배열: 문자열.chars(), 문자열.toCharArray()
- 특정: 문자열.charAt()
- 대소문자 구분: Character.isLowerCase(ch)
- 배열
- 정렬: Arrays.sort()
- 문자열
- 정렬: StringBuilder.reverse()
- 대소문자 구분 x: equalsIgnoreCase()
- 반복: repeat()
- 형변환
- int[] -> List : Arrays.stream(arr).boxed().collect(Collectors.toList())
- Long.parseLong, Integer.parseInt()
Stream
- collect(): Collectors.toList(), StringBuilder 대신 Collectors.joining()
- 정렬: sorted()
용어
- 약수: divisor
- 배수: multiple
- 소수: prime