이어서 알고리즘 문제 풀이를 진행했다.
오늘 풀었던 문제에 대해서 회고해보고자 한다.
내림차순으로 배치하기
주어진 문자열을 내림차순으로 배치하여 반환하는 문제이다.
import java.util.Arrays;
import java.util.Collections;
public class StringDescendingOrder {
public String solution(String s) {
String[] strArr = s.split("");
Arrays.sort(strArr, Collections.reverseOrder());
StringBuffer str = new StringBuffer();
for (int i = 0; i < strArr.length; i++) {
str.append(strArr[i]);
}
return str.toString();
}
public static void main(String[] args) {
StringDescendingOrder obj = new StringDescendingOrder();
String answer = obj.solution("Zbcdefg");
System.out.println(answer);
}
}
for문으로 문자열을 계속 변환해주어야하기 때문에 StringBuilder를 선언하여 사용했다.
Arrays.sort()와 Collections.reversOrder() 는 계속 유용하게 사용하는 것 같다.
StringBuilder를 다시 String으로 변환할 땐, toString()을 사용하면 된다.
소수 만들기
배열에 주어진 숫자 중 3개를 더하고, 그 숫자가 소수인지 판별하는 문제이다.
class Solution {
public int solution(int[] nums) {
int answer = 0;
for (int i = 0; i < nums.length; i++) {
for (int j = i+1; j < nums.length; j++) {
for (int k = j+1; k < nums.length; k++) {
int sum = nums[i] + nums[j] + nums[k];
for(int l=2; l < sum ; l++){
if(sum%l == 0){
//더해진 수 전까지 나누어 떨어진다면 소수가 아니므로 for문 정지
break;
}
if(l == sum-1){
answer++;
}
}
}
}
}
return answer;
}
}
3개의 숫자를 순차적으로 어떻게 섞을 수 있을지 고민했는데, 3중 for문을 사용했다.
소수는 1과 자기자신을 약수로 가지는 수를 말한다.
따라서, 1은 모든수의 약수이므로 조건식에서 제외하고, 2부터 더해진 숫자까지 반복해서 비교했을 때, 그 전에 약수가 존재한다면 소수가 아니게 되므로 for문을 벗어나도록 했다.
숫자 문자열과 영단어
영단어를 숫자로 문자열로 변환하여 반환하는 문제이다.
class Solution {
String[] strArr = {"zero","one","two","three",
"four","five","six","seven","eight","nine"};
public int solution(String s) {
for(int i = 0; i<10; i++){
s = s.replace(strArr[i], Integer.toString(i));
}
return Integer.parseInt(s);
}
}
이 풀이 방법을 알기 전에, HashMap을 가지고 문제를 풀려했는데, 훨씬 간단한 방법이여서 이 방법으로 다시 코드를 짜보았다. 변환하기 위해서 문자를 쪼개고, 그 값을 다시 비교해서 변환하고.. 쓸데없이 코드가 길어졌었는데 replace 함수가 있다는 것을 까먹고 있었다..
replace를 활용하니 엄청 간단하게 풀려서 허탈한 문제였던 것 같다.
시저 암호
주어진 n의 수 만큼 문자를 밀어서 변환하는 문제이다. (문자는 대문자, 소문자로만 이루어져있다.)
class Solution {
public String solution(String s, int n) {
String answer = "";
String[] strArr = s.split("");
for(int i = 0; i < strArr.length; i++){
if (strArr[i].equals(" ")){
answer += " ";
continue;
}
int asci = strArr[i].charAt(0); //각 글자 Char로 변환
if(65 <= asci && asci <= 90){ // A-Z까지
asci = (asci - 65 + n) % 26;
//a or A로 돌아오는 것까지 포함해서 26임
answer += String.valueOf((char)(asci + 65));
}
if(97 <= asci && asci <= 122){ //a-z까지
asci = (asci - 97 + n) % 26;
answer += String.valueOf((char)(asci + 97));
}
}
return answer;
}
}
Char로 변환하여 아스키코드를 이용하는 것은 알겠는데, 각 Z 또는 z 에서 1을 더했을 때 다시 A 또는 a가 되도록 식을 구현하는게 고민이였던 문제이다.
아스키코드 값에 a만큼의 코드값을 빼고, n을 더한후에 26의 나머지를 구하면 몇칸을 움직여야하는지 구할 수 있다.
90-65 ➞ 25로 나머지 계산을 진행했는데 계속 한칸이 더 밀리는 현상이 발생해서 직접 세어보니, 26으로 나머지를 구해야 정확하다는 것을 알 수 있었다. (z➞a 하는 횟수 포함)
신규 아이디 추천
주어진 조건대로 아이디를 수정하여 반환하는 문제이다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
class Solution {
public String solution(String new_id) {
//replaceAll 활용하기.
// long before = Runtime.getRuntime();
// 1단계
String answer = new_id.toLowerCase();
// 2단계
answer = answer.replaceAll("[^-_.a-z0-9]",""); //-_. a부터z 0부터 9가 아니면 공백으로
// 3단계
answer = answer.replaceAll("[.]{2,}","."); // .이 2번 반복이면 .으로 ,의 의미?
// 4단계
answer = answer.replaceAll("^[.]|[.]$",""); // 시작과 끝이 .이면 "으로
// 5단계
if(answer.equals("")){
answer += "a";
}
// 6단계
if(answer.length() >= 16){
answer = answer.substring(0, 15);
answer = answer.replaceAll("[.]$",""); // 문자열 끝에 .이면 삭제
}
// 7단계
if(answer.length() <= 2){
while(answer.length() < 3){
answer += answer.charAt(answer.length()-1);
}
}
return answer;
}
}
키워드는 replace가 맞는 것 같다. replace를 사용하지 않은채로 직접 조건식을 짜서 값을 구해보았는데 가독성이 매우 좋지 않고 지저분한 코드가 나왔다.
다른 사람 풀이를 보니 정규식을 쓰면 획기적으로 코드가 줄어드는 것을 알고 정규식 코드를 보면서 구현을 해보았다.
정규표현식 기호
그동안 너무나도 괴랄한 형태??에 공부하길 꺼려했었는데 직접 하나씩 뜯어보면서 사용하니 나름 이해가 잘 되었던 것 같다. replaceAll을 이용한 예제를 몇개 풀어보면서 익숙해질 수 있도록 해봐야겠다.
느낀 점
함수만 알고있었더라면 시간을 많이 단축할 수 있는 상황이 자주 발생했다. 문제를 직접 부딪혀 풀어보는 것도 좋지만, 어느정도 시간이 지나면 답을 보면서 코드를 분석하여 내 것으로 만드는 것도 좋은 방법이라는 생각이 들었다.
내일은 알고리즘 모의고사가 진행된다. 문제가 그렇게 어렵지는 않을 것으로 예상되지만, 동영상 녹화 등 해보지 않았던 작업들이 몇 가지 있기 때문에 아침에 일어나서 미리 대비해두어야 겠다.
'항해99' 카테고리의 다른 글
항해 99 - 2023.02.01 TIL (1) | 2023.02.01 |
---|---|
항해 99 - 2023.01.31 TIL (0) | 2023.01.31 |
항해99 - 3주차 WIL (0) | 2023.01.30 |
항해 99 - 2023.01.28 TIL (0) | 2023.01.28 |
항해 99 - 2023.01.27 TIL (0) | 2023.01.27 |