자바스크립트에서 문자열에 포함된 특정 문자의 개수를 구해야 하는 경우가 있다. 특정 문자를 구하는 직접적인 함수는 없으며 split 함수와 match 함수를 활용하여 특정 문자의 개수를 구할 수 있다.
아래의 예제는 문자열에서 특정 문자 쉼표(',')의 개수를 구하는 방법이다.
split 함수 사용
var str = 'HTML,CSS,JavaScript'; var count = str.split(',').length - 1; // 결과 : 2split 함수를 사용하여 문자열을 배열로 변환 후 배열의 크기에서 -1을 하면 특정 문자의 개수를 구할 수 있다.
split 함수를 사용하면 특정 문자를 기준으로 문자열을 배열로 변환한다.
배열의 길이에서 -1 만큼이 특정 문자 개수이다.
match 함수 사용
var str = 'HTML,CSS,JavaScript'; var count = str.match(/,/g).filter(function(item) { return item !== ''; }).length; // 결과 : 2match 함수를 사용하면 특정 문자를 추출하여 배열로 반환한다.
특정 문자가 없을 경우 빈 배열을 반환하는데 이럴 경우 filter 함수를 사용하여 빈 배열을 제거해야 0을 얻을 수 있다.
filter 함수를 사용하지 않을경우 특정 문자를 찾지 못하면 빈배열 1개를 반환하기 때문에 1을 반환한다.
var str = 'HTML,CSS,JavaScript'; var count = str.match(/,/g).filter(item => item !== '').length; // 결과 : 2위의 소스코드와 동일한 기능이며 화살표 함수를 사용하여 코드의 길이를 줄였다.
IE 브라우저에서는 화살표 함수를 지원하지 않는다.
match 함수를 사용하면 특정 문자를 추출하여 배열로 반환하는 것을 확인할 수 있다.
배열의 개수가 특정 문자가 개수가 된다.
[JavaScript] 문자열 특정 문자 위치 찾기 (indexOf, search)
자바스크립트에서 문자열에서 문자 또는 문자열의 위치를 검색 위해서는 indexOf와 search 함수를 사용하고, 문자열의 뒤에서 부터 문자열을 검색할 때는 lastIndexOf 함수를 사용하면 된다. str.index
gent.tistory.com
[백준] 2675번 : 문자열 반복 - JAVA [자바]
//www.acmicpc.net/problem/2675
2675번: 문자열 반복
문제 문자열 S를 입력받은 후에, 각 문자를 R번 반복해 새 문자열 P를 만든 후 출력하는 프로그램을 작성하시오. 즉, 첫 번째 문자를 R번 반복하고, 두 번째 문자를 R번 반복하는 식으로 P를 만들면 된다. S에는 QR Code "alphanumeric" 문자만 들어있다. QR Code "alphanumeric" 문자는 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\$%*+-./: 이다. 입력 첫째 줄에 테스트 케이스의 개수 T(1
www.acmicpc.net
문제
그리 어렵지 않은 문제다.
다만 Scanner 을 이용하여 풀 경우 조심해야 할 것이 있기 때문에 포스팅하면서 이에 대해 설명해주겠다.
- 3가지 풀이 방법을 제시한다.
먼저
가장 기본적인 입력방법인 Scanner 을 통해 풀어볼 것이다.
그 다음으로 Scanner 대신 BufferedReader 을 이용하여 풀어 볼 것이고, 다음으로 BufferedReader 로 입력을 받지만 알고리즘은 다르게 하여 풀 것이다.
- 풀이
- 방법 1
가장 기본적인 방법이라 할 수 있겠다.
그리고 반드시 문자열 S 를 입력받을 때 Scanner.nextLine() 이 아닌 Scanner.next() 로 입력받아야 한다.
nextLine() 으로 입력받으면 입력 과정에서 공백까지 읽어버리기 때문이다.
무슨 말인가 하면 위의 예제를 보면 다음과 같이 입력을 받는다.
2 3 ABC 5 /HTP그런데 nextLine() 은 엔터값을 입력받을 때까지 기준으로 한 줄을 읽어버린다.
반면에 next() 는 공백을 기준으로 하나의 문자열만 읽어들인다.
만약 nextLine() 으로 입력 받았을 경우 공백까지 읽어들이기 때문에 다음과 같은 출력 결과가 나타난다.
AAABBBCCC // 3개의 공백이 출력됨 /////HHHHHTTTTTPPPPP // 5개의 공백이 출력됨즉, nextLine() 은 3과 ABC 사이에 있는 공백까지 읽어들이기 때문에 위와 같은 현상이 나타나므로 반드시 next() 로 문자열을 입력받아야 한다.
- 방법 2
Scanner 대신 BufferedReader 을 쓰는 방법이다.
다만 Scanner 와 달리 BufferedReader.readLine() 은 한 줄을 통째로 읽기 때문에 split() 이나 StringTokenizer 로 숫자와 문자열 사이의 공백을 구분해주어야 한다.
여기서는 split() 메소드를 사용하기로 한다.
그리고 분리된 문자의 첫번째는 int 형으로 변환해야하므로 Integer.parseInt() 를 사용하여 String 에서 int 형으로 변환시켜준다.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); int T = Integer.parseInt(br.readLine()); for(int i = 0; i < T; i++) { String[] str = br.readLine().split(" "); // 공백 분리 int R = Integer.parseInt(str[0]); // String -> int String S = str[1]; for(int j = 0; j < S.length(); j++) { for(int k = 0; k < R; k++) { System.out.print(S.charAt(j)); } } System.out.println(); } } }
- 방법 3
좀 더 효율적인 방법은 없을까?
일단 출력(System.out) 을 너무 자주 호출해주는 것 같으니 출력을 한 번만 호출하도록 변경해보자.
또한 약간의 알고리즘을 간소화해보기 위해 charAt() 이 아닌 getBytes() 로 반환하도록 변경해보겠다.
말로 설명하려니 뭔가 싶겠지만 막상 코드 보면 이해가 될 것이다.
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringBuilder sb = new StringBuilder(); int T = Integer.parseInt(br.readLine()); for (int i = 0; i < T; i++) { String[] str = br.readLine().split(" "); int R = Integer.parseInt(str[0]); for (byte val : str[1].getBytes()) { for (int j = 0; j < R; j++) { sb.append((char)val); } } sb.append('\n'); } System.out.print(sb); } }- 성능
위에서 부터 순서대로
채점 번호 : 18543956 - BufferedReader + StringBuilder ( 방법 3 )
채점 번호 : 18543947 - BufferedReader ( 방법 2 )
채점 번호 : 18543939 - Scanner ( 방법 1 )
입력의 경우는 확실히 Scanner 보다는 BufferedReader 가 빠른 걸 볼 수 있다.
또한 출력 메소드의 호출 빈도를 낮춰주니 시간이 더욱 단축되었다.
- 정리
아마 평소에 BufferedReader 을 쓰던 분들이면 어렵지 않게 풀었을 것 같다.
다만 Scanner 의 경우 nextInt(), next(), nextLine() 에 대하여 정확히 어떤 방식으로 입력을 받고 구분되는지에 대해 알고있지 않았다면 충분히 틀렸을법한 문제다.