1byte를 사용해 알파벳, 공백, 쉼표, 특수문자 등을 표현하는 문자체계. 최상위 비트는 0으로 고정되어 있으며 7bit를 사용한다. 영어를 제외한 다른 언어를 나타낼 수 없다.
영어를 제외한 다른 언어를 표현하기 위해 ASCII에서 비어있는 구간(128 ~ 256)에 해당하는 공간을 활용하는 체계이다. 하지만 각 언어별로 제한된 공간을 사용하는 방법이 다르다보니, 표준화된 양식을 제공하기 어렵다.
국제 표준화 기구에 의해 개발된 문자체계. 2Byte를 기준으로 개발되었으며, 각 언어별로 고유한 공간을 제공받는다. 하지만 데이터양을 간소화할 수 있는 언어(ex. 영어)들도 동일하게 문자 하나에 2Byte를 사용해야한다는 점에서 단점이 존재한다.
가변 길이를 지원하는 문자체계. 언어별로 최적화된 공간에 문자를 저장하며, 영문은 1byte 한글은 3byte를 사용한다.
String [변수] = new String("문자열","인코딩 형식");
String str = new String("안녕하세요", "UTF-8");
byte [배열 이름][] = [String 이름].getBytes("인코딩 형식");
byte array[] = str.getBytes("unicode");
error: unmappable character (0xEC) for encoding x-windows-949
컴파일 시 위와 같은 에러가 발생한다면 인코딩 옵션을 추가하면 된다.
javac (...생략...) -encoding [인코딩 형식]
javac (...생략...) -encoding utf-8
Scanner로 입력을 받을 땐, 자료형을 구분하여 입력받는 것이 깔끔하다. 쓸데 없는 타입변환은 지양하자.
Scanner scanner = new Scanner(System.in);
System.out.print("Grid의 크기를 입력하세요(X * X): ");
int inputNumber = scanner.nextInt();
for (int i = 0; i < inputNumber; i++){
String tmp = null;
while (tmp == null){
System.out.printf("%d번째 라인을 입력하세요: ", i+1);
tmp = scanner.nextLine();
}
알고리즘 문제를 풀 때 사용했던 코드를 잘라왔다. 먼저 scanner.nextInt();를 통해 입력된 정수를 받고, 이후 scanner.nextLine();를 통해 String을 받아내는 간단한 코드이다. 하지만 실행을 해보면, scanner.nextLine();의 리턴 값이 비어있는 것을 확인 할 수 있다.
유저에 의해 입력된 값들은 큐 형태로 저장된다. 유저가 100을 입력했다면, 큐에 저장된 내용은 다음과 같다.
Queue <- [100][Enter]
scanner.nextInt(); 메소드는 Enter나 Space를 기준으로 가장 가까운 int를 반환한다. 반환된 이후 큐에 저장된 내용과 변수에 저장된 내용은 다음과 같다.
Queue <- [Enter]
inputnumber <- [100]
scanner.nextLine(); 메소드는 Enter를 기준으로 이전에 입력된 String을 반환한다. 반환된 이후 큐에 저장된 내용과 변수에 저장된 내용은 다음과 같다.
Queue <- (비어있음)
inputnumber <- [100]
tmp <- (비어있음)
Enter 이전에 입력된 값이 없기 때문에, tmp에는 아무런 정보도 저장될 수 없으며 결국 Enter까지 큐에서 정상적으로 빠져 나왔기 때문에 컴파일에도, 실행에도 에러가 없다.
Enter를 중간에 빼주기만 하면 된다. 어렵게 얘기해서 버퍼 초기화지, 결국 scanner.nextLine();을 한번 더 호출해 큐에서 Enter를 제거해주면 된다.
Scanner scanner = new Scanner(System.in);
System.out.print("Grid의 크기를 입력하세요(X * X): ");
int inputNumber = scanner.nextInt();
scanner.nextLine(); // 버퍼초기화
for (int i = 0; i < inputNumber; i++){
String tmp = null;
while (tmp == null){
System.out.printf("%d번째 라인을 입력하세요: ", i+1);
tmp = scanner.nextLine();
}
public class Array_Copy{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4 };
int[] b = a;
}
}
public class Array_Copy{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4 };
int[] b = new int[a.length];
for (int i = 0; i < a.length; i++) {
b[i] = a[i];
}
}
}
public class Array_Copy{
public static void main(String[] args) {
int[] a = { 1, 2, 3, 4 };
int[] b = a.clone();
}
}
Deep Copy 관련 포스트를 작성하게된 이유다. clone();을 사용해 2차원 배열을 Deep Copy하고자 했었다. Deep Copy가 안된 건 의심조차 하지 못한채 원하는 결과가 안나와 메소드 두 어개를 새로 작성하며 몇 번씩 컴파일을 했는데, 범인은 clone();이었다.
"array[x][y]" 형태의 2차원 배열 구조에서, clone();을 사용하면 y좌표를 가르키는 array[x] 부분만 Deep Copy가 된다고 한다. ㅂㄷㅂㄷ
방법은 크게 두 가지로, for문을 돌리는 방법과 System.arraycopy();를 사용하는 방법이 있다. 퍼포먼스 차이가 날지는 모르겠지만, Class를 호출하기보단 for문을 돌리는게 마음 편할 것 같다.
public class Array_Copy{
public static void main(String[] args) {
int a[][] = {{1,2,3},{4,5,6,},{7,8,9}};
int[][] b = new int[a.length][a[0].length];
for(int i=0; i<a.length; i++) {
for(int j=0; j<a[i].length; j++) {
b[i][j] = a[i][j];
}
}
}
}
public class Array_Copy{
public static void main(String[] args) {
int a[][] = {{1,2,3},{4,5,6,},{7,8,9}};
int b[][] = new int[a.length][a[0].length];
for(int i=0; i<b.length; i++){
System.arraycopy(a[i], 0, b[i], 0, a[0].length);
}
}
}