문자열 문제중 정규표현식 문제와 정규표현식을 따로 정리해 놓겠다.
정규표현식의 기본 규칙이다.
자주 사용 되는 규칙이다.
이 외에 규칙들이다.
/^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/i | 이메일 |
/^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$/ | 핸드폰 번호 |
백준 1013 (Contact)
1013번: Contact
입력의 첫 줄에는 테스트 케이스의 개수 T가 주어진다. 그 다음 줄부터 각각의 테스트 케이스에 대해 전파를 표현하는, { 0, 1 }만으로 이루어진 문자열이 공백 없이 주어진다. 문자열 길이는 (1 ≤
www.acmicpc.net
이 문제에서는 문제 자체에 정규식을 어떻게 써야 답을 구할 수 있는지 나와있어서 문제를 푸는 방법 자체는 어렵지 않았다.
문제에 적힌 정규식 규칙을 읽어보고 이해하는 것이 더 중요한 문제같다.
(100+1+ | 01)+ 를 사용하면 100_1_ (여기서 _ 에는 문자가 1개이상 있으면 된다)와 01 패턴이 반복되는 코드를 찾을 수 있다.
<전체 코드>
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import javax.management.Query;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class Main {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bufferedReader.readLine());
String regex = "(100+1+|01)+";
for(int i = 0 ; i < n ; i++){
String test = bufferedReader.readLine();
if(Pattern.matches(regex, test)) {
sb.append("YES\n");
}
else {
sb.append("NO\n");
}
}
System.out.println(sb);
}
}
백준 2857번 (FBI)
https://www.acmicpc.net/problem/2857
2857번: FBI
5개 줄에 요원의 첩보원명이 주어진다. 첩보원명은 알파벳 대문자, 숫자 0~9, 대시 (-)로만 이루어져 있으며, 최대 10글자이다.
www.acmicpc.net
이 문제의 경우 두가지 풀이법이 존재한다.
정규식 만으로 푸는 문제와
자바에 존재하는 정규식 함수를 이용하여 푸는 방식이다.
첩보원명에 FBI가 존재하는지를 확인하면 된다.
정규식 ".*FBI.*" 를 통해 찾을 수 있다.
" .* " -> 이 정규식에서 . : . 의 위치에 어떤 문자가 와도 된다.
* : 0개이상의 문자가 온다.
이 두가지 규칙이 합쳐져 0개이상의 문자가 .의 위치에 온다. 쉽게말해 모든 단어를 선택할 수 있는 것이다.
코딩테스트에서 해당 문자를 포함하는 지를 고르는 문제가 많이 나오니까 알아두면 좋겠다.
<정규식 만으로 찾기>
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import javax.management.Query;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class Main {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String regex = ".*FBI.*";
int cnt = 0;
for(int i = 1 ; i <= 5 ; i++){
String name = bufferedReader.readLine();
if(Pattern.matches(regex, name)) {
cnt++;
sb.append( i + " " );
}
}
if(cnt == 0) {
sb.append("HE GOT AWAY!");
}
System.out.println(sb);
}
}
자주 사용되는 정규식 함수
- matches() -> 패턴에 정확하게 일치하는지 확인
- replaceAll() -> 패턴에 맞는 값을 새로운 값으로 치환
- find() -> 패턴에 맞는 값이 하나라도 존재하는지(Boolean)
- group() -> 패턴에 맞는 값의 첫번째 문자의 위치(Integer)
이렇게 존재한다.
mathces() 함수는
Pattern 에 존재하는 함수다.
나머지 함수는
Matcher 에 존재하는 함수들이다.
포함되는지의 유무를 알고 싶은 문제이므로 find() 를 사용하면 된다.
Pattern pattern = Pattern.compile(regex);
Matcher match = pattern.matcher(name);
if(match.find()) {
cnt++;
sb.append( i + " " );
}
Pattern 을 이용해 Matcher 를 생성하는 코드를 익혀놓으면 편하게 사용할 수 있을 것이다.
<정규식 함수를 이용한 풀이>
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import javax.management.Query;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class Main {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String regex = "FBI";
int cnt = 0;
for(int i = 1 ; i <= 5 ; i++){
String name = bufferedReader.readLine();
Pattern pattern = Pattern.compile(regex);
Matcher match = pattern.matcher(name);
if(match.find()) {
cnt++;
sb.append( i + " " );
}
}
if(cnt == 0) {
sb.append("HE GOT AWAY!");
}
System.out.println(sb);
}
}
백준 2617(잠수함 식별)
2671번: 잠수함식별
입력에 들어있는 스트링을 읽고, 이것이 잠수함의 엔진소리를 나타내는 스트링인지 아니면 그냥 물속의 잡음인지를 판정한 후, 잠수함의 엔진 소리에 해당하는 스트링이면 "SUBMARINE"을 출력하고
www.acmicpc.net
위의 1013번을 풀어봤으면 쉬운 문제다.
(100~1~|01)~ 은 1013번에서 (100+1+|01)+ 와 같은 말이다.
<전체 코드>
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import javax.management.Query;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class Main {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
String regex = "(100+1+|01)+";
if(Pattern.matches(regex, bufferedReader.readLine())) {
sb.append("SUBMARINE");
}
else {
sb.append("NOISE");
}
System.out.println(sb);
}
}
백준 2870 (수학숙제)
2870번: 수학숙제
종이에서 찾은 숫자의 개수를 M이라고 하면, 출력은 M줄로 이루어져야 한다. 각 줄에는 종이에서 찾은 숫자를 하나씩 출력해야 한다. 이때, 비내림차순으로 출력해야 한다. 비내림차순은 내림차
www.acmicpc.net
여기서 사용하는 건
split() 함수다
split() 함수는 String 에서 해당 정규표현식에 해당하는 문자가 나오면 나눠주는 역할을 한다.
여기서 사용할 정규식은 숫자만 저장을 해야하므로 숫자를 제외한 나머지 문자들이다.
"\D" - \D 는 숫자를 제외한 나머지 숫자들을 말한다. ( = "[^0-9]")
여기서 java 는 \ 를 표현하려면 \\ 두개를 적어야 하나가 되므로 밑 코드에선 \\D 가된다.
Integer 을 사용하면 런타임 오류가 뜨므로
BigInteger 을 이용하여 문제를 풀었다. ( Long 을 사용했는데 런타임 에러가 똑같이 났다)
<전체 코드>
import java.io.*;
import java.math.*;
import java.security.*;
import java.text.*;
import java.util.*;
import java.util.concurrent.*;
import java.util.function.*;
import java.util.regex.*;
import java.util.stream.*;
import javax.management.Query;
import static java.util.stream.Collectors.joining;
import static java.util.stream.Collectors.toList;
public class Main {
static StringBuilder sb = new StringBuilder();
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(bufferedReader.readLine());
List<BigInteger> ans = new LinkedList<BigInteger>();
for(int i = 0 ; i < n ; i++) {
String[] line = bufferedReader.readLine().split("\\D");
for(int j = 0 ; j < line.length ; j++) {
if(!line[j].equals("")) {
ans.add(new BigInteger(line[j]));
}
}
}
Collections.sort(ans);
for(BigInteger num : ans) {
sb.append(num + "\n");
}
System.out.println(sb);
}
}
'자료구조 공부 > String' 카테고리의 다른 글
백준 1701 (Cubeditor) (0) | 2021.04.20 |
---|---|
백준 1062 (가르침) (0) | 2021.04.20 |
백준 1786 (찾기) (0) | 2021.03.23 |
백준 9935 (문자열 폭발) (0) | 2021.03.19 |
백준 1958 ( LCS 3) (0) | 2021.03.19 |