문제
첫 줄에 100 이하의 자연수 N을 입력받고,
둘째 줄에 N개의 숫자를 공백 없이 입력받는다.
입력받은 숫자들의 합을 구한다.
풀이
- 입력받는 수의 자릿수가 0~100이므로 int, long으로 받을 수 없다.
- 데이터 표현 범위
- int : -2,147,483,648 ~ 2,147,483,647 -> 최대 10자리
- long : -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807 -> 최대 19자리
- 따라서 String으로 입력받고 각 자릿수를 int형으로 변환한 후 덧셈해야 한다.
- 3가지 방법을 사용
(1) Scanner + charAt() + getNumericValue()
(2) BufferedReader + charAt()
(3) BufferedReader + getBytes()
코드
(1) Scanner + charAt() + getNumericValue()
import java.util.*;
public class Main {
public static void main(String[] args){
//갯수 입력받기
//갯수만큼 숫자 입력받기(공백없이) >> String으로 받기
//charAt()으로 하나씩 떼서 int로 변경
//덧셈 후 출력
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
String str = sc.next();
int sum = 0;
for(int i=0; i<N; i++) {
sum += Character.getNumericValue(str.charAt(i));
}
System.out.println(sum);
}
}
java.lang.Character.getNumericValue(char)는 숫자 형태의 char을 int로 변환하는 메서드이다.
(2) BufferedReader + charAt()
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int N = Integer.parseInt(br.readLine());
String str = br.readLine();
int sum = 0;
for(int i=0; i<N; i++) {
sum += str.charAt(i)-'0';
//sum += str.charAt(i)-48;
}
System.out.println(sum);
}
}
str.charAt(i)
먼저, 문자열을 이루는 문자 하나하나를 char로 변경한다.
sum += str.charAt(i)-'0'
//또는
sum += str.charAt(i)-48
char값에 '0'값(문자 '0'의 유니코드값) 또는 숫자 48을 빼준다.
- 자바는 피연산자를 4byte 단위로 저장하므로, 2byte인 char타입이라도 둘이 연산을 하게 되면 자동으로 4byte인 int타입으로 변환되어 계산된다. 예를 들어 '5'와 '4'라는 char형 문자 간에 뺄셈을 하면 두 문자가 int타입의 유니코드 값으로 변환된 후 연산이 이루어진다. 문자 '5'의 유니코드 값은 53, 문자 '4'의 유니코드 값은 52이므로 result에는 정수값 1이 저장된다.
char c1 = '5';
char c2 = '4';
int result = c1 - c2; //'5'의 유니코드 값 - '4'의 유니코드 값 저장
- 유니코드 (Unicode)
문자 | '0' | '1' | '2' | '3' | '4' | '5' |
10진 | 48 | 49 | 50 | 51 | 52 | 53 |
- 자바에서는 문자 상수가 사용될 때 이를 해당 문자의 유니 코드 값으로 간주한다. 따라서 '0'이라는 문자 상수는 해당 문자의 유니 코드 값인 48로 간주된다. '0'과 48은 같은 의미이다.
따라서 char형 문자에 -48
또는 -'0'
을 해주면 문자와 동일한 정수값을 구할 수 있다.
(3) BufferedReader + getBytes()
import java.util.*;
import java.io.*;
public class Main {
public static void main(String[] args)throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
int sum = 0;
br.readLine();
//for-each문으로 문자를 하나씩 읽는다.
for (byte res : br.readLine().getBytes()){ //readLine()으로 읽어들인 문자열을 byte[]로 변환하여 반환한다.
sum += res-'0'; //UTF-16(유니코드 인코딩 방식)에 맞게 각 문자의 값을 저장하므로 '0'또는 48을 뺀다.
}
bw.write(sum+" ");
bw.close();
}
}
- java.lang.String.getBytes() 메서드
- String 포함 메서드이기 때문에 import할 필요가 없다.
- 유니코드 문자열(String)을 지정된 charset을 사용해 바이트코드로 인코딩하고, 새로운 byte 배열에 결과를 저장해 반환하는 메서드이다.
- 만약 getBytes()의 인자로 charset을 넘기지 않으면 사용자 플랫폼의 기본 charset으로 인코딩된다. 자바는 UTF-16을 사용한다.
아래에서부터 차례로
(1) Scanner + charAt() + getNumericValue()
(2) BufferedReader + charAt()
(3) BufferedReader + getBytes()
Note
- 명시적 타입 캐스팅을 했을 때 char값은 아스키코드값으로 변경된다.
char c = '1'; int result_1 = (int)c; //char형 '1'을 int로 명시적 타입캐스팅 //1의 아스키코드값 출력
//49
int result_2 = Character.getNumericValue(c); //char값이 int로 변경됨
//1
- String.prototype.split()도 String 객체를 지정한 구분자를 이용하여 여러 개의 문자열로 나누는 메서드이다.
하지만 구분자로 빈 문자열("")을 제공하면, 유니코드 문자 하나씩으로 나누는 것이 아니라 UTF-16 으로 나누게 되며 써로게이트 페어가 망가질 수 있다. - 인코딩 : 사람이 이해하는 언어(문자, 숫자, 기호) -> 컴퓨터가 이해하는 언어(0, 1)
- 디코딩 : 인코딩의 반대
- charset : 인코딩을 위한 규칙 (ex. ASCII CODE, UNICODE..)
- charset마다 인코딩 방식이 하나씩 있는데, UNICODE는 UTF-8(HTML), UTF-16(JAVA) 두 가지가 있다.
'BOJ' 카테고리의 다른 글
[백준 2675번/JAVA] 문자열 반복 (0) | 2024.03.08 |
---|---|
[백준 10809번/JAVA] 알파벳 찾기 | 문자열 (2) | 2024.03.07 |
[백준 9086번/JAVA] 문자열 | String.valueOf(), subString() | String.valueOf()와 toString()의 차이점 (0) | 2024.03.05 |
[백준 1546번/JAVA] 평균 | 배열 (0) | 2024.03.05 |
[백준 10811번/JAVA] 바구니 뒤집기 | 배열 (0) | 2024.03.05 |