자바 사용자 문자열 몇 번 포함되는지

자바스크립트에서 문자열에 포함된 특정 문자의 개수를 구해야 하는 경우가 있다. 특정 문자를 구하는 직접적인 함수는 없으며 split 함수와 match 함수를 활용하여 특정 문자의 개수를 구할 수 있다.

아래의 예제는 문자열에서 특정 문자 쉼표(',')의 개수를 구하는 방법이다.

split  함수 사용

var str = 'HTML,CSS,JavaScript'; var count = str.split(',').length - 1; // 결과 : 2

split 함수를 사용하여 문자열을 배열로 변환 후 배열의 크기에서 -1을 하면 특정 문자의 개수를 구할 수 있다.

split 함수를 사용하면 특정 문자를 기준으로 문자열을 배열로 변환한다.

배열의 길이에서 -1 만큼이 특정 문자 개수이다.

match  함수 사용

var str = 'HTML,CSS,JavaScript'; var count = str.match(/,/g).filter(function(item) { return item !== ''; }).length; // 결과 : 2

match 함수를 사용하면 특정 문자를 추출하여 배열로 반환한다.

특정 문자가 없을 경우 빈 배열을 반환하는데 이럴 경우 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 [자바]

  • 2020.03.19 20:02
  • JAVA - 백준 [BAEK JOON]/문자열


//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 

import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int T = in.nextInt(); for(int i = 0; i < T; i++) { int R = in.nextInt(); String S = in.next(); // nextLine() 을 쓰면 error! for(int j = 0; j < S.length(); j++) { for(int k = 0; k < R; k++) { // R 만큼 반복 출력 System.out.print(S.charAt(j)); } } System.out.println(); } } }

가장 기본적인 방법이라 할 수 있겠다.

그리고 반드시 문자열 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() 에 대하여 정확히 어떤 방식으로 입력을 받고 구분되는지에 대해 알고있지 않았다면 충분히 틀렸을법한 문제다.

Toplist

최신 우편물

태그