Day2 - 문자열 돌리기
📌 문제 정보
- 문제 이름 : 코딩 기초 테스트 - 문자열 돌리기
- 문제 링크: https://school.programmers.co.kr/learn/courses/30/lessons/181945
📌 문제 요약
- 핵심 조건: 문자열 str을 시계방향으로 90도 돌려서 아래 입출력 예와 같이 출력하는 코드를 작성
- 제한: 1 ≤ str ≤ 10
📌 내 풀이 및 코드
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str = sc.next();
for (int i = 0; i <= str.length(); i++) {
System.out.println(str.charAt(i));
}
}
}
- 출력 값이 제대로 나오긴 한데 " IndexOutOfBoundsException"이 발생함. (인덱스 범위 벗어나서 비정상 종료됨.)
- i <= str.length() 가 문제였음. 문자열 인덱스는 0부터 시작해서 length - 1까지라서.
- Ex) input = abcde : length = 5, index = 0, 1, 2, 3, 4 (5-1)
근데 내 코드는 <=이기 때문에 0, 1, 2, 3, 4, 5까지 돌고, strcharAt(5)가 존재하지 않기 때문에 Exception이 발생함.
📌 다른 사람들 풀이
// 1
for (int i = 0; i < str.length(); i++) {
System.out.println(str.charAt(i));
}
// 2
for (char ch : str.toCharArray())
System.out.println(ch);
// 3
Arrays.stream(a.split("")).forEach(System.out::println);
<-- 다른 풀이 요약 -->
- 1 : 내 풀이에 대한 정확한 코드 및 정답. ('<=' 가 아니고 '<' 가 답임.)
- 2 : for-each문 + toCharArray() : 문자열을 문자 배열로 변환하고 그 배열을 for-each로 순회함.
- 3 : split(" ") + Stream + forEach
* split("")로 문자열을 빈 문자 기준으로 쪼갬 -> String[] 배열이 생김. ex) abc -> ["a", "b", c"]
* Arrays.stream() : 배열을 스트림으로 만듦.
* for-each문으로 하나씩 출력
| 방법 | 특징 | 장점 | 단점 |
| 1. 전통 for + charAt | 인덱스 직접 접근 | 빠름, 제어 자유 | 인덱스 실수 가능 |
| 2. toCharArray() + for-each | char 배열로 순회 | 가독성 좋음, 안전 | 배열 생성 오버헤드 |
| 3. split("") + Stream | String 배열 + 함수형 | 매우 간결, 람다 사용 | split이 정규식이라 느림, Stream 오버헤드 있음 |
📌 새로 배운 문법
<-- 이번 문제에서 새로 배운 Java 문법 정리 -->
** Exception (예외) **
- Java에서 Exception이 뜨면 프로그램이 무조건 멈춤.
- IndexOutofBoundsException : 런타임 예외(Runtime Exception) => 컴파일은 되지만 실행하다가 터짐.
** for-each문 심화 정리**
- for-each문 = 확장 for문
- 배열이나 리스트의 모든 원소를 순서대로 꺼낼 때 쓰는 가장 간단한 반복문
// 1. 기본 for-each문 작성방법
for(타입 변수명(자료형 변수) : 콜렉션명(배열 or 리스트)) {
// 반복할 코드
}
// 2. 예시 (1) - char 배열
char[] arr = {'a', 'b', 'c'};
for (char ch : arr) { // arr에 있는 원소 a, b, c를 ch에 하나씩 담아 반복함
System.out.println(ch);
}
// 3. 예시 (2) - 문자열
String str = "abc";
for (char ch : str.toCharArray()) {
System.out.println(ch);
}
=> 바로 str 쓸 수 없음. toCharArray()를 통해 char[] 형식으로 바꿔야함.
** Arrays.stream() + forEach **
- 배열을 Stream으로 바꿔서 람다식으로 처리하는 함수형 스타일
- 리스트나 배열을 한 번에 가공, 필터, 출력할 때 유용함.
- Stream이란? 데이터(배열, 리스트 등)를 흐름(stream)으로 만들어서 반복 처리, 가공, 필터링, 합계 같은걸 쉽게 하는 도구.
| 종류 | 메서드 | 설명 | 예시 |
| 생성 | stream() | 컬렉션에서 Stream 생성 | list.stream() |
| Arrays.stream() | 배열에서 Stream 생성 | Arrays.stream(arr) | |
| 중간 연산 | filter() | 조건에 맞는 요소만 걸러냄 | .filter(x -> x > 0) |
| map() | 요소를 다른 값으로 변환 | .map(x -> x * 2) | |
| sorted() | 정렬 | .sorted() | |
| distinct() | 중복 제거 | .distinct() | |
| limit() | 앞에서 n개만 | .limit(5) | |
| skip() | 앞에서 n개 건너뜀 | .skip(2) | |
| 최종 연산 | forEach() | 요소 하나씩 처리 | .forEach(System.out::println) |
| collect() | 결과를 List 등으로 모음 | .collect(Collectors.toList()) | |
| count() | 개수 세기 | .count() | |
| sum() | 합계 (IntStream 등) | .mapToInt(x -> x).sum() | |
| max() | 최대값 | .max() | |
| min() | 최소값 | .min() | |
| anyMatch() | 조건 만족하는 요소 있는지 | .anyMatch(x -> x > 5) | |
| allMatch() | 모두 조건 만족하는지 | .allMatch(x -> x > 0) |
- 중간 연산 : Stream 유지, 최종 연산 : Stream 닫힘
// 1. 기본 문법
Arrays.stream(배열).forEach(원소를 처리하는 람다);
// 2. 예시
List<Integer> list = List.of(1, 2, 3, 4, 5);
int sum = list.stream() // Stream 생성
.filter(x -> x % 2 == 0) // 짝수만
.map(x -> x * 2) // 2배
.sum(); // 합계 (IntStream)
System.out.println(sum); // 12 (2*2 + 4*2)
(어려우니까 다시 보기...)