단어 뒤집기 / ArrayList, StringBuilder
설명
N개의 단어가 주어지면 각 단어를 뒤집어 출력하는 프로그램을 작성하세요.
입력
첫 줄에 자연수 N(3<=N<=20)이 주어집니다.
두 번째 줄부터 N개의 단어가 각 줄에 하나씩 주어집니다. 단어는 영어 알파벳으로만 구성되어 있습니다.
출력
N개의 단어를 입력된 순서대로 한 줄에 하나씩 뒤집어서 출력합니다.
예시 입력 1
3
good
Time
Big
예시 출력 1
doog
emiT
giB
소스코드 1
import java.util.Scanner;
public class Main {
public static void solution(String str) {
for (int i = str.length() - 1; i >= 0; i--) {
System.out.print(str.charAt(i));
}
System.out.println();
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt(); // 단어의 개수
for (int i = 0; i < N; i++) {
String str = sc.next();
solution(str);
}
}
}
소스코드 2 (ArrayList, StringBuilder)
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static ArrayList<String> solution(int n, String[] str) {
ArrayList<String> answer = new ArrayList<>();
for (String x : str) {
String s = new StringBuilder(x).reverse().toString(); //단어를 뒤집어준다
answer.add(s); //뒤집은 단어 ArrayList에 추가
}
return answer;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
String[] str = new String[N];
for (int i = 0; i < N; i++) {
str[i] = sc.next();
}
for (String s : solution(N,str)) { //solution 메서드는 거꾸로 된 단어들의 배열 반환
System.out.println(s);
}
}
}
ArrayList : 컬렉션 클래스
- ArrayList<String> list = new ArrayList<String>(); -> String 타입을 저장할 수 있는 ArrayList 생성한다.
- 요소 추가 방법
- add() 메서드를 이용해서 추가한다.
- list.add("a"); // list에 "a" 추가
- 요소 접근 방법
- get(index) 메서드를 이용해서 접근한다.
- list.get(0); // list의 0번째 인덱스에 접근
- 요소 제거 방법
- remove(index) 메서드를 이용해서 제거한다
- list.remove(0); // list의 0번째 인덱스 요소 제거
- list.size() : list의 크기 반환
- ArrayList 전체 요소 출력
- for (String str : list){
Systemout.print(str)
}
ArrayList와 배열은 모두 자바에서 사용되는 데이터를 저장하는 방법이다.
그러면 두 저장법의 차이는 무엇일까 ?
1. 크기조정
- 배열을 사용하면서 불편한 점으로는 크기가 한 번 결정되면 변경하지 못하는 것이다.
이에 반해 ArrayList는 크기를 동적으로 조정할 수 있다. 요소를 추가하거나 제거하면 크기가 자동으로 조정이 된다.
2. 타입 안정성
- 배열은 기본 타입과 객체 모두 저장 가능하고 ArrayList는 객체만 저장 가능하다.
또한 ArrayList는 제네릭을 사용하여 특정타입의 객체만 저장하게 함으로써 안정성을 제공한다
3. 성능
- 배열은 메모리에서 연속적인 공간을 사용하기 때문에 인덱스를 통한 접근이 매우 빠른 반면
ArrayList는 내부적으로 배열을 사용하긴 하지만, 크기 조정 로직 때문에 배열보다는 속도가 느릴 수 있다.
- 상황에 따라서 효율적인 저장법을 선택하면 된다.
- 크기가 변하지 않고, 성능이 중요하다 -> 배열
- 크기가 유동적이고, 타입 안정성이 중요하다. -> ArrayList
StringBuilder : 문자열을 효율적으로 조작할 수 있게 해주는 클래스
- StringBuilder(x) : x를 객체로 만든다
- StringBuilder(x).reverse.toString() : x를 뒤집어 준 후 String 타입으로 반환해 준다.
StringBuilder와 String의 차이점
1. 성능
- String 객체는 불변이기 때문에 문자열을 바꿀 때 마다 객체가 새로 생성된다.
하지만 StringBuilder는 내부적으로 문자열을 바꿀 수 있어서 문자열 연산이 많을 경우 성능이 향상된다.
2. 메모리 효율
- StringBuilder는 내부버퍼를 사용하고 필요에 따라 크기를 유동적으로 변경시킬 수 있다.
따라서 문자열의 변경이 생겨도 객체의 생성이 없기 때문에 메모리 효율이 더 좋다.
3. 가독성
- StringBuilder를 사용하면 복잡한 문자열 조작을 읽기 쉬운 코드로 작성할 수 있다.
또한 메서드 체이닝을 통해 여러 문자열 연산을 한 줄로 작성할 수 있다.
문자열의 변경이나 추가가 많다면 StringBuilder가 효율적이다. 문자열 변경이 없거나 드문 경우는 String이 효율적일 수 있음.
소스코드 3 (직접 인덱스 교환)
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static ArrayList<String> solution(int n, String[] str) {
ArrayList<String> answer = new ArrayList<>();
for (String x : str) {
int lt=0;
int rt = x.length() - 1;
char[] s = x.toCharArray();
while (lt < rt) {
char tmp = s[lt];
s[lt] = s[rt];
s[rt] = tmp;
lt++;
rt--;
}
answer.add(String.valueOf(s));
}
return answer;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
String[] str = new String[N];
for (int i = 0; i < N; i++) {
str[i] = sc.next();
}
for (String s : solution(N,str)) {
System.out.println(s);
}
}
}
str.toCharArray()
- str을 String에서 char 타입의 배열로 바꿔준다.
- String s = "Hello World" 라는 문자열이 있을 때 char[] c = s.toCharArray()를 사용해주면 c라는 char배열로 바꿔준다.
String.valueOf()
- 다양한 타입을 String 타입으로 바꿔준다.
- char c ='a' 라는 변수가 있을 때 String.valueOf(c)를 실행하면 c를 String 타입의 "a"로 바꿔준다.
- null을 인자로 받을 경우 "null" 문자열을 반환한다.