코딩 테스트를 볼 때 문자열을 가지고 장난치는 문제가 상당히 많이 나옵니다. 문자열 문제가 나왔을 때 대처할만한 메서드들을 공부해 보려고 합니다.
문자에 대해
문자의 배열
String.charAt(int index) // 문자 하나를 가져온다.
String.toCharArray() // 모든 문자를 한 번에 배열로 가져온다.
- charAt은 하나하나씩 호출하므로 메서드 호출에 따른 오버헤드가 있습니다.
- toCharArray()는 문자열 길이에 해당하는 메모리를 사용합니다.
아스키코드
아스키코드도 문제를 풀 때 정말 많이 사용했습니다. 특히 Char를 int로 바꿀 때 자주 사용했습니다.
char digit = '10';
int digitToInt = digit - '0';
대문자를 소문자로 소문자를 대문자로 바꿀 때도 아스키코드를 사용합니다. 대문자 'A' ~ 'Z'는 65 ~ 90이고 소문자 'a' ~ 'z'는 97~112입니다.
char lower = 'e';
char upper = (char) (lower + ('a' - 'A'));
char upper = 'E';
char lower = (char) (upper - ('a' - 'A'));
// 많이 쓰는 메소드
Char lower = 'e';
Char upper = Character.toUpperCase(lower);
Char upper = 'G';
Char lower = Character.toLowerCase(upper);
문자열에 대해
StringBuilder
StringBuilder도 자주 사용한다. String은 생성을 하면 새로운 객체를 생성하지만 StringBuilder는 객체에 추가하는 형식이라 문자열을 쉽고 효율적으로 구성할 수 있다.
메소드 | 역할 | 시간 복잡도 |
StringBuilder.toString() | 지금까지 구성한 문자열을 String 형식으로 반환한다. | O(N) |
StringBuilder.append(char c) | 문자 c를 문자열 끝에 이어 붙인다. | O(1) |
StringBuilder.length() | 지금까지 구성한 문자열 길이를 반환한다. | O(1) |
StringBuilder.reverse() | 지금까지 구성한 문자열을 뒤집는다. | O(N) |
isAlphabetic()
Character가 가지고 있는 isAlphabetic()에는 알파벳인지 아닌지 검사할 수 있다.
문자열 응용하기
메소드 | 반환형 | 내용 |
equals(String other) | boolean | 문자열이 other와 같은 문자열을 담고 있는지 반환 |
length() | int | 문자열 길이를 반환 |
substring(int beginIndex, int endIndex) | String | 문자열의 beginIndex부터 endIndex까지 잘라서 반환 |
toUpperCase() | String | 모든 알파벳이 대문자로 변환된 문자열을 반환 |
toLowerCase() | String | 모든 알파벳이 소문자로 변환된 문자열을 반환 |
진법 바꾸기
메소드 | 반환형 | 내용 |
Integer.parseInt(String s) | int | 숫자를 표현하는 문자열 S를 정수로 변환 |
Integer.toString(int v) | String | 정수 v를 문자열로 변환 |
Long.parseLong(String s) | long | 숫자를 표현하는 문자열 s를 정수로 변환 |
Long.toString(Long v) | String | 정수 v를 문자열로 변환 |
메소드 | 반환형 | 내용 |
Integer.parseInt(String s, int radix) | int | radix 진법으로 숫자를 표현하는 문자열 s를 정수로 변환 |
Integer.toString(int v, int radix) | String | 정수 v를 radix 진법의 문자열로변 |
Long.parseLong(String s, int radix) | long | radix 진법으로 숫자를 표현하는 문자열 s를 정수로 변환 |
Long.toString(long v, int radix) | String | 정수 v를 radix 진법의 문자열로 변환 |
String binary = "1010";
int value = Integer.parseInt(binary,2 ); // 2진법을 정수로 변환
String hex = Integer.toString(value, 16);
찾기와 바꾸기
메소드 | 반환형 | 내용 |
contains(CharSequence s) | boolean | 전달받은 문자열이 원본 문자열에 있는지 검사 |
startsWith(String prefix) | boolean | 원본 문자열이 전달받은 문자열로 시작하는지 검사 |
endsWith(String suffix) | boolean | 원본 문자열이 전달받은 문자열로 끝나는지 검사 |
indexOf(String str) | int | 전달받은 문자열이 원본 문자열에서 몇 번째 인덱스에 있는지 검사 |
replace(char oldChar, char newChar) | String | 원본 문자열의 oldChar 문자들을 newChar 문자로 치환한 문자열을 반환 |
replace(CharSequence target, CharSequence replacement) | String | 원본 문자열에서 등장하는 target 문자열을 replacement 문자열로 치환해서 반환하는 메서 |
정규표현식에 대해
코테를 풀면서 정규표현식을 사용해 본 적은 없습니다. 하지만 알맞은 문자열을 찾을 때는 정규표현식 또 하나의 강한 무기가 될 수 있을 것 같습니다. 그래서 간단한 정규표현식은 공부해 보려고 합니다.
정규표현식 | 내용 | 예시 |
. | 개행 문자를 제외한 아무 문자 | .nd -> and, end, .... |
[abc] | a, b, c 중 아무것이나 | [ae]nd -> and, end |
[^abc] | a, b, c를 제외하고 | [^ae]nd -> cnd, nnd, ... |
[a-g] | a, g 사이의 문자들 [0-9] -> 모든 숫자 [a-z] -> 모든 소문자 [A-Z] -> 모든 대문자 |
[1-9][0-9] -> 10부터 2자리수 [A-Z][a-z] -> An, Ba, ... |
a* | a 0개 이상 | 1[0-9]* -> 1, 10, 150... |
a+ | a 1개 이상 | 1[0-9]+ -> 10, 164, ... |
a? | a 0개 또는 1개 | 1[0-9]? -? 1, 11, 15, ... |
a{5} | a가 5개 | [a-c]{3, } -> a, aa, ab, ac, .. |
a{2, } | a가 2개 이상 | [a-c]{3,} -> a, aa |
a{2, 4} | a가 2개 이상 4개 이하 | [a-c] {2,3} -> aa, aab, ... |
ab|cd | ab 또는 cd | |
^a | 문자열의 처음 문자가 a | |
a$ | 문자열의 마지막 문자가 a | |
\ | 사전 정의된 문자를 표현하는 이스케이프 시퀀스 | \. -> . \+ -> | |
메서드 | 반환형 | 내용 |
replaceAll(String regex, String replacement) | String | 전달받은 정규표현식에 매칭되는 패턴을 모두 replacement로 치환 |
matches(String regex) | boolean | 문자열이 전달받은 정규표현식에 매칭되는지 여부를 반환 |
split(String regex) | String[] | 전달받은 정규표현식에 매칭되는 패턴을 기준으로 원본 문자열을 잘라서 반 |
https://school.programmers.co.kr/learn/courses/30/lessons/72410
1단계 new_id의 모든 대문자를 대응되는 소문자로 치환합니다.
2단계 new_id에서 알파벳 소문자, 숫자, 빼기(-), 밑줄(_), 마침표(.)를 제외한 모든 문자를 제거합니다.
3단계 new_id에서 마침표(.)가 2번 이상 연속된 부분을 하나의 마침표(.)로 치환합니다.
4단계 new_id에서 마침표(.)가 처음이나 끝에 위치한다면 제거합니다.
5단계 new_id가 빈 문자열이라면, new_id에 "a"를 대입합니다.
6단계 new_id의 길이가 16자 이상이면, new_id의 첫 15개의 문자를 제외한 나머지 문자들을 모두 제거합니다.
만약 제거 후 마침표(.)가 new_id의 끝에 위치한다면 끝에 위치한 마침표(.) 문자를 제거합니다.
7단계 new_id의 길이가 2자 이하라면, new_id의 마지막 문자를 new_id의 길이가 3이 될 때까지 반복해서 끝에 붙입니다.
위 문제는 이렇게 7단계를 지나가면서 id를 검사해야 하는 문제입니다. 이 문제를 정규표현식으로 쉽게 처리할 수 있습니다.
class Solution {
public String solution(String newid) {
newid = newid.toLowerCase();
newid = newid.replaceAll("[^a-z0-9\\-_.]","");
newid = newid.replaceAll("\\.+",".");
newid = newid.replaceAll("^\\.+|\\.+$","");
if(newid.isEmpty()) newid = "a";
if(newid.length() >= 16){
newid = newid.substring(0,15);
newid = newid.replaceAll("\\.+$","");
}
while(newid.length() < 3){
newid += newid.charAt(newid.length() - 1);
}
return newid;
}
}
출처
https://product.kyobobook.co.kr/detail/S000200928002
'코딩테스트 공부 > 알고리즘 공부' 카테고리의 다른 글
불량 사용자 (프로그래머스) JAVA (0) | 2023.07.28 |
---|---|
쿼드압축 후 개수 세기(프로그래머스) JAVA (0) | 2023.07.27 |
거리두기 확인하기(프로그래머스) JAVA (0) | 2023.06.24 |
삼각 달팽이(프로그래머스) JAVA (0) | 2023.06.21 |
교점에 별 만들기(프로그래머스) JAVA (0) | 2023.06.20 |