문제
: N개의 단어가 주어지면 , 각 단어를 뒤집어 출력하는 프로그램 작성
EX)
이 문제의 요구사항은 말 그대로 입력받은 각 문자열을 역전시키는 것이므로,
나는 아래와 같은 해결로직으로 이 문제를 해결하였다.
1) 일단 N개의 문자열을 String 배열에 담는다.
2) 이후 각각의 String에 대하여, [마치 char 배열의 index 접근 방식과 같이] String 클래스의 인스턴스 메서드 charAt() 을 사용한다.
- 그러면 String을 구성하는 각 char별로 index 접근을 할 수 있고
- 이에 따라 length-1 번 char부터 0번 char까지 순서대로 출력하므로써
- 문제에서 요구하는 각 String별 역순 출력을 하게 된다.
위 로직을 기반으로 한 나의 코드는 다음과 같다.
import java.util.Scanner;
public class Main {
public static void solution(String[] strArr){
// 각각의 String에 대해서, charAt() 메서드를 통해 인덱스기반 접근으로 역순 출력
for (String s : strArr) {
for(int i = s.length()-1; i>=0; i--){
System.out.print(s.charAt(i));
}
System.out.println();
}
}
public static void main(String[] args){
//0. Scanner 준비
Scanner sc = new Scanner(System.in);
//1. N 입력
int N = sc.nextInt();
//1_2. N개의 element를 갖는 String Array 생성
String[] strArr = new String[N];
//2. N줄에 걸쳐 N개의 String 입력
for(int i=0; i<N; i++){
strArr[i] = sc.next();
}
//3. 입력받은 String들이 담긴 strArr를 solution()을 호출하면서 인자로 넘김 -> solution()에서 각 String들의 element들을 뒤집어서 출력
solution(strArr);
}
}
문제를 해결하면서 알게된 점 또는 정리할 점
1) String 클래스의 인스턴스 메서드 charAt()를 이용하면 , 그 String을 구성하는 각 char값을 index 기반으로 접근할 수 있다.
2) 이때의 인덱스 값은 c언어의 char 배열과 같이 0부터 순서대로 시작한다.
3) 따라서 이 charAt() 메서드만 잘 사용하면, String 객체를 char배열로 바라보고 더 다양한 작업을 할 수 있을것이다.
4) 추가적으로 이 문제를 StringBuilder를 써서 다시 풀어보면서, Scanner를 통해 입력받는 부분에서 for-each문을 사용했었는데,
for-each문은 배열의 값에 하나씩 접근하는 것일 뿐, 배열을 구성하는 각 변수 자체에 접근하는 것은 아니니, for-each 로는 값을 입력받을 수 없음을 깨달음.
하지만 선생님께서는 StringBuilder 클래스를 사용하여 , 훨씬 더 직관적인 코드로 문제를 해결하셨다.
우선 StringBuilder 클래스에 대해서는 아래와 같이 간략하게 정리할 수 있다.
[StringBuilder 클래스]
: 말 그대로 String을 만들어 주는 역할 수행
- 왜 StringBuilder라는 문자열을 별도로 만들어주는 역할이 필요한가를 묻는다면,
- String 객체가 "한번 생성되면 변경이 불가능한 Immutable 객체" 이기 때문이라고 답할 수 있다.
실제로 String 객체가 Immutable 객체이기 때문에, 이들을 가지고 수행하는 연산 과정에서 크고 작은 메모리 낭비가 일어난다.
일 예로 두 문자열을 연결하는 문자열 덧셈 상황을 살펴보자.
String str = "hello " + "world";
위 코드가 실행되면 실제로는 "hello " 와 "world" 라는 두 String 객체를 생성한 후, 이들을 이어붙이는게 아니라 -> "hello world"라는 새로운 String 객체를 생성한다.
String 객체는 한번 생성되면 변할 수 없는 Immutable 객체이기 떄문이다.
이러한 Immutable 객체의 동작 방식은 결과적으로 쓸데없는 메모리의 해체와 할당으로 이어지게 된다.
따라서 이런 측면을 보완하고자 문자열을 더 효율적으로 만들 수 있는 StringBuilder 클래스가 등장하였다.
그리고 우리는 이 StringBuilder 클래스가 제공하는 reverse() 메소드를 사용하여 아래와 같이 문자열을 쉽게 뒤집을 수 있다.
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;
public class Main2 {
public static List<String> solution(String[] strArr){
//String 배열을 구성하는 각각의 String에 대해서
//StringBuilder 객체로 만든 후 - 여기서 제공하는 reverse()를 호출하여 문자열을 뒤집은 후 -> toString()으로 다시 String으로 만들어줌
List<String> strList = Arrays.stream(strArr)
.map(s -> new StringBuilder(s).reverse().toString())
.collect(Collectors.toList());
return strList;
}
public static void main(String[] args){
//0. Scanner 준비
Scanner sc = new Scanner(System.in);
//1_1. N 입력
int N = sc.nextInt();
//1_2. String[N] 의 배열 생성
String[] strArr = new String[N];
//2. N줄에 걸쳐서 각 문자열을 입력받아 배열에 저장
for(int i=0; i<N; i++){
strArr[i] = sc.next();
}
//3. 배열을 통째로 solution()으로 넘겨 , reverse된 String 배열 반환
List<String> strList = solution(strArr);
//4. 출력
strList.stream()
.forEach(s -> System.out.println(s));
}
}