손에 잡히는 10분 정규 표현식 표지

 

http://www.yes24.com/Product/Goods/75454395

 

독서기간 : 2022.08

독서시간 : 2H

평점 : ★★★★★

한줄평 : 텍스트, 문자를 다루는 레벨을 올릴 수 있는 책이다.

 

일을 하다 보면 다양한 곳에서 정규표현식과 만나게 된다.

정규표현식을 볼때마다 항상 든 생각이 언젠가 한번 제대로 정리하여 개발생산성을 높이고 싶다 였는데, 괜찮은 책이 없을까 찾다가 발견하여 보게 되었다.

 

인터넷에서 필요할 때마다 찾아보면 쉬워 보이면서도 직접 쓰려고 하면 정리가 제대로 되지 않아서 활용하기가 쉽지 않은데, 잘 정리된 내용을 하나씩 읽어가면서 체계를 잡을 수 있어서 큰 도움이 되었다.

 

정규식을 공부한 뒤 가끔씩 여러 조건들을 넣어서 필요한 정보만 빠르게 검색하면 정말 뿌듯해진다.

여유가 난다면 꼭 공부하기를 추천한다.

'독서 > IT 기술' 카테고리의 다른 글

[독서/IT 기술] 토미의 Git with 소스트리  (0) 2022.08.07

함께 자라기 책 표지

http://www.yes24.com/Product/Goods/67350256

 

함께 자라기 - YES24

‘함께’는 협력을 말하고, ‘자라기’는 학습을 말한다. 무엇이건 실제 바깥세상(야생)에 임팩트를 남기려면 혼자 힘으로만 되는 게 없다. 함께 해야 한다. 주변 사람들과 함께. 매일 부대끼는

www.yes24.com

독서기간 : 2022.08

독서시간 : 5H

평점 : ★★★★★

한줄평 : 사람들이 함께 일하면서 같이 성장할 수 있는 협업방법에 대해 배울 수 있음

 

크고 복잡한 일들, 더 큰 성과를 내기 위해서는 혼자서 하는 것보다 여러 사람들이 함께 일을 해야 한다.

학교에서도 선생과 학생이 함께 학생의 성장이라는 목표로 협력하며, 회사에서 일을 할 때도 회사의 이익이라는 목표를 위해서 다양한 사람들이 협력하여 일을 한다.

 

일을 더 잘하기 위해서, 더 큰 성과를 내기 위해서는 어떻게 해야할까? 

회사든 학교든 결국 모든 일은 사람들이 하는 것이기 때문에, 사람들이 성장해야 회사도 성장하고 성취할 수 있는 결과도 더 커지게 된다.

 

함께 일을 하면서, 단지 목표만 보고 달려가는 것이 아니라 더 큰 관점에서 조직과 사람이 성장하는 방법에 대한 통찰력을 배울 수 있는 책이었다. 이전까지는 단순히 열심히 일에 집중하고, 부족한 부분은 스스로 찾아서 배우는 개개인의 역량에 의지하는 방식으로 일을 처리하였는데, 더 큰 성과를 내기 위해서는 일을 바라보는 시각이 개인에서 확대하여 같이 일하는 사람들을 바라보고, 그 사람들과 어떻게 협력하고 커뮤니케이션 하여 서로 윈윈할수 있을지 알게 되었다.

 

내가 알게된 내용을 주변 사람들과 함께 공유하고 현실에서 성과로 이뤄내는 것은 또 다른 문제이지만, 같이 일하는 사람들에게 선물해주고 싶은 책이다.

https://school.programmers.co.kr/learn/courses/30/lessons/42577

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제

전화번호부에 적힌 전화번호 중, 한 번호가 다른 번호의 접두어인 경우가 있는지 확인하려 합니다.
전화번호가 다음과 같을 경우, 구조대 전화번호는 영석이의 전화번호의 접두사입니다.

  • 구조대 : 119
  • 박준영 : 97 674 223
  • 지영석 : 11 9552 4421

전화번호부에 적힌 전화번호를 담은 배열 phone_book 이 solution 함수의 매개변수로 주어질 때, 어떤 번호가 다른 번호의 접두어인 경우가 있으면 false를 그렇지 않으면 true를 return 하도록 solution 함수를 작성해주세요.

제한 사항

  • phone_book의 길이는 1 이상 1,000,000 이하입니다.
    • 각 전화번호의 길이는 1 이상 20 이하입니다.
    • 같은 전화번호가 중복해서 들어있지 않습니다.

입출력 예제

phone_bookreturn
["119", "97674223", "1195524421"] false
["123","456","789"] true
["12","123","1235","567","88"] false

입출력 예 설명

입출력 예 #1
앞에서 설명한 예와 같습니다.

입출력 예 #2
한 번호가 다른 번호의 접두사인 경우가 없으므로, 답은 true입니다.

입출력 예 #3
첫 번째 전화번호, “12”가 두 번째 전화번호 “123”의 접두사입니다. 따라서 답은 false입니다.

 

발상

정렬을 하면 앞뒤 비교만으로 간단하게 해결될 것 같아서 정렬 후 순서대로 하나의 문자열을 그 다음 문자열이 포함하고 잇는지 여부를 검사하는 방식으로 접근하였다.

의사코드

1. 입력값 정렬
2. 배열수+1 만큼 반복{
	1. 다음 배열의 값이 현재 배열의 값을 가지고 있으면 false
}
3. true 리턴

 

코드

더보기
        if (phone_book.length == 1) return true;
        Arrays.sort(phone_book);
        for (int i = 0; i < phone_book.length - 1; i++) {
            String pattern = "^"+phone_book[i]+".*";
            if(phone_book[i+1].matches(pattern)) return false;
//            if(phone_book[i+1].contains(phone_book[i])) return false;
//            if (phone_book[i].length() <= phone_book[i + 1].length() && phone_book[i].equals(phone_book[i + 1].substring(0, phone_book[i].length())))
//                return false;
//            for (int j = i+1; j < phone_book.length; j++) {
//                if (phone_book[j].contains(phone_book[i])) {
//                    return false;
//                }
//            }
        }
        return true;
    }

개선

처음엔 contains로 접근하였는데, 테스트케이스를 통과하지 못하는 예외케이스가 발생하였다.

생각해보니 제시된 문자열로 시작하는 경우만 검사해야 하기 때문에, substring으로 수정하여 통과시켰다가

다시 정규식으로 전환하였는데, 정규식은 패턴문자열을 계속해서 만들어야 하다 보니까 성능이 훨씬 안나왔다.

토미의 Git with 소스트리 책 표지

http://www.yes24.com/Product/Goods/109651011

 

토미의 Git with 소스트리 - YES24

이 책은 두 개의 파트로 구성돼 있다. 파트I에서는 Git의 기본 개념에 대해 설명 했다. 파트2에서는 Git의 여러 명령을 사용하는 방법에 대해 설명했다. 이 책을 반드시 처음부터 읽을 필요는 없다.

www.yes24.com

 

독서기간 : 2022.07.12 ~ 2022.07.25

독서시간 : 5H

평점 : ★★★★★

한줄평 : Git에 대해서 동작원리부터 실제사례까지 공부할 수 있음

 

개발 공부를 시작하거나 취직 후 개발자로 일을 하게 되면 형상관리도구를 사용하게 된다.

구글의 도움을 받아서 사용법을 익히고, 깃허브 아이디도 만들고 개인 프로젝트에서도 사용해보았지만, 지금 일하고 있는 회사에서는 SVN을 사용하고 있어서 Git을 개인적으로 사용할 때마다 더 체계적이고 잘 정리된 사용법이 있지 않을까? 하는 갈증이 있었다.

Git같은 경우는 강의로 들을 만큼 내용이 어렵거나 많은 것도 아니라 어떻게 공부하면 좋을까 고민한 결과 출퇴근 시간에 ebook으로 읽으면 괜찮겠다 생각해서 바로 교보문고에서 sam베이직으로 빌려서 독서를 시작했다.

 

본문 구성이 신입사원이 입사하여 개발자로 일하면서 git에 대한 필요성을 느끼고 사수에게 배운다는 시나리오를 설정하면서 스토리를 풀어가면서 얘기하는데, 딱딱한 기술이야기만 있는 것보다 친근감있게 다가와서 읽기 좋았고, 챕터도 출퇴근시간에 하나씩 읽기 적당한 단위로 나뉘어져 있어서 1주일정도 걸려서 완독을 하였다.

 

단순 사용법만 나열한 것이 아니고 버전관리의 역사부터 git의 주요 오브젝트, 어떤 방식으로 작동하는지 잘 정리되어 있으며, 소스트리를 통해 실제 사용 예제도 책에 삽입된 이미지를 보면서 시각적으로 볼 수 있어서 컴퓨터앞에 앉아있지 않아도 이해가 쉽게 되었다.

 

'독서 > IT 기술' 카테고리의 다른 글

[독서/IT 기술] 손에 잡히는 10분 정규 표현식  (0) 2022.10.02

리눅스에서 쉘스크립트를 확인하다 보면 볼 수 있는 인자값 $*과 $@이 있다.

검색해보면 둘 다 인자값을 넘겨주는 변수인데 어떤 차이가 있는지 알아보았다.

 

$* expands to all parameters that were passed to that shell script.
$0 = shell script's name
$1 = first argument
$2 = second argument ...etc
$# = number of arguments passed to shellscript

 

It means all the arguments passed to the script or function, split by word.
It is usually wrong and should be replaced by "$@", which separates the arguments properly

 

리눅스에서 사용되는 명령어들은 인자값을 받을 수 있다.

예를들면 도커 이미지를 실행하는 명령어는 다음과 같다.

docker start [images]

위의 명령어를 보면 docker 명령어에, start와 images 인자를 함께 전달하여 명령어를 실행한 것인데

 

$* 같은 경우는 넘어온 모든 인자들을 하나의 문자열로 보기 때문에

[start images]라고 인식을 하며

 

$@ 같은 경우는 넘오온 인자들을 각각의 인자로 인식하기 때문에

start / images 로 인식하게 된다.

 

위에 언급한 인용문처럼 일반적으로 $*는 잘못된 사용법이며, $@로 바꿔야 한다고 이야기하고 있다.

 

참고

 

https://stackoverflow.com/questions/12413848/what-does-mean-in-a-shell-script

 

what does $* mean in a shell script

What does $* exactly mean in a shell script? For example consider the following code snippet $JAVA_HOME/bin/java/com/test/Testclass $*

stackoverflow.com

 

 

'IT > VS' 카테고리의 다른 글

[JavaScript] NPM vs Yarn  (0) 2023.07.14
[Java] StringBuilder VS BufferedWriter  (0) 2023.04.02
[ VS]arguments VS parameter  (0) 2021.09.23

 

증상

Invalid barcode

The barcode [URL] is not a valid authentication token barcode
 

구글 Authentication 앱을 사용해서 MFA 시스템을 구축하였는데 안드로이드에선 잘 작동하지만 IOS 아이폰에선 작동하지 않는 현상이 발생하였다.

 

다요소 인증 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. RSA SecurID 토큰. 어디에도 연결되지 않은 토큰 생성기의 예. 다요소 인증(多要素認證, Multi-factor authentication, MFA)은 적어도 다음 분류 중 두 가지에 한해 별도의 여

ko.wikipedia.org

 

원인

구글 Authentication은 TOTP 를 구현하여 작동한다. 해당 알고리즘에서 키값을 암호화 하는데 BASE32 인코딩을 사용하였는데, 인코딩 된 결과값이 자리수를 맞추기 위해 더해지는 패딩문자 '='가 IOS에서 인식하지 못하여 발생하는 문제였다.

 

시간 기반 일회용 비밀번호 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 시간 기반 일회용 비밀번호(Time-based one-time password, TOTP)는 현재 시간을 고유성의 원천으로 사용하여 일회용 비밀번호 (OTP)를 생성하는 컴퓨터 알고리즘이다. HMAC

ko.wikipedia.org

 

해결책

처음에는 URL 인코딩을 처리하면 해결될 줄 알았는데, 여전히 같은 에러가 발생하였다.

테스트를 진행하다 보니 패딩된 문자 '='는 복호화시 제거하여도 같은 값을 돌려주는 무의미한 문자여서 제거하고 테스트하였더니 아이폰에서도 정상작동하였다.

https://school.programmers.co.kr/learn/courses/30/lessons/42586

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제

프로그래머스 팀에서는 기능 개선 작업을 수행 중입니다. 각 기능은 진도가 100%일 때 서비스에 반영할 수 있습니다.

또, 각 기능의 개발속도는 모두 다르기 때문에 뒤에 있는 기능이 앞에 있는 기능보다 먼저 개발될 수 있고, 이때 뒤에 있는 기능은 앞에 있는 기능이 배포될 때 함께 배포됩니다.

먼저 배포되어야 하는 순서대로 작업의 진도가 적힌 정수 배열 progresses와 각 작업의 개발 속도가 적힌 정수 배열 speeds가 주어질 때 각 배포마다 몇 개의 기능이 배포되는지를 return 하도록 solution 함수를 완성하세요.

제한 사항

  • 작업의 개수(progresses, speeds배열의 길이)는 100개 이하입니다.
  • 작업 진도는 100 미만의 자연수입니다.
  • 작업 속도는 100 이하의 자연수입니다.
  • 배포는 하루에 한 번만 할 수 있으며, 하루의 끝에 이루어진다고 가정합니다. 예를 들어 진도율이 95%인 작업의 개발 속도가 하루에 4%라면 배포는 2일 뒤에 이루어집니다.

발상

스택과 큐 카테고리에 있는 문제인데, 실제 자료구조를 구현해서 쓰기에는 애매했다.

자료구조에 들어가 있는 값들을 모두 다뤄야 하는데, 스택과 큐 기본 자료구조는 양 끝점에 있는 데이터 외에는 다룰 수 없어서 개념적으로 구현하여 사용하였다.

의사코드

1. 초기값 세팅
2. 예상되는 배포일 반복(제한조건 100일){
	1. 개발 진척도 상승
    2. 1번아이템 개발완료 체크
    	1. 개발 실패시 다음 일로
        2. 개발 성공시 카운트 증가 및 다음아이템 개발완료 체크
]
3. 결과값 반환

 

코드

더보기
private int index = 0;
private int answerIndex = 0;

public int[] solution(int[] progresses, int[] speeds) {
    ArrayList<Integer> answerList = new ArrayList<>();
    int cnt;
    //전체순회
    for (int j = 0; j < 100; j++) {
        if (index >= progresses.length) break;
        // 1번에 개발완료된 수
        cnt = 0;
        // 1회 개발 진행, 진척도 상승
        for (int i = 0; i < progresses.length; i++) {
            progresses[i] += speeds[i];
        }
        // 젤 처음 개발완료 체크
        if (progresses[index] < 100) continue;
        // 개발 성공
        index++;

        cnt++;
        cnt += isMoreDeveloped(progresses, index);
        answerList.add(cnt);
        answerIndex++;
    }

    return answerList.stream().mapToInt(a -> a).toArray();
}

private int isMoreDeveloped(int[] progresses, int innerIndex) {
    if (innerIndex >= progresses.length) return 0;
    if (progresses[innerIndex] >= 100) {
        innerIndex++;
        this.index++;
        return 1 + isMoreDeveloped(progresses, innerIndex);
    }
    return 0;
}

개선

아직 스트림 사용법이 미숙하고 선언해둔 변수가 코드를 작성하다보니 쓰이지 않는 등 의사코드 작성 능력이 부족한 것 같다.

 

 
 
 
 

https://school.programmers.co.kr/learn/courses/30/lessons/92334

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제

신입사원 무지는 게시판 불량 이용자를 신고하고 처리 결과를 메일로 발송하는 시스템을 개발하려 합니다. 무지가 개발하려는 시스템은 다음과 같습니다.

  • 각 유저는 한 번에 한 명의 유저를 신고할 수 있습니다.
    • 신고 횟수에 제한은 없습니다. 서로 다른 유저를 계속해서 신고할 수 있습니다.
    • 한 유저를 여러 번 신고할 수도 있지만, 동일한 유저에 대한 신고 횟수는 1회로 처리됩니다.
  • k번 이상 신고된 유저는 게시판 이용이 정지되며, 해당 유저를 신고한 모든 유저에게 정지 사실을 메일로 발송합니다.
    • 유저가 신고한 모든 내용을 취합하여 마지막에 한꺼번에 게시판 이용 정지를 시키면서 정지 메일을 발송합니다.

다음은 전체 유저 목록이 ["muzi", "frodo", "apeach", "neo"]이고, k = 2(즉, 2번 이상 신고당하면 이용 정지)인 경우의 예시입니다.

유저 ID유저가 신고한 ID설명
"muzi" "frodo" "muzi"가 "frodo"를 신고했습니다.
"apeach" "frodo" "apeach"가 "frodo"를 신고했습니다.
"frodo" "neo" "frodo"가 "neo"를 신고했습니다.
"muzi" "neo" "muzi"가 "neo"를 신고했습니다.
"apeach" "muzi" "apeach"가 "muzi"를 신고했습니다.

각 유저별로 신고당한 횟수는 다음과 같습니다.

유저 ID신고당한 횟수
"muzi" 1
"frodo" 2
"apeach" 0
"neo" 2

위 예시에서는 2번 이상 신고당한 "frodo"와 "neo"의 게시판 이용이 정지됩니다. 이때, 각 유저별로 신고한 아이디와 정지된 아이디를 정리하면 다음과 같습니다.

유저 ID유저가 신고한 ID정지된 ID
"muzi" ["frodo", "neo"] ["frodo", "neo"]
"frodo" ["neo"] ["neo"]
"apeach" ["muzi", "frodo"] ["frodo"]
"neo" 없음 없음

따라서 "muzi"는 처리 결과 메일을 2회, "frodo"와 "apeach"는 각각 처리 결과 메일을 1회 받게 됩니다.

이용자의 ID가 담긴 문자열 배열 id_list, 각 이용자가 신고한 이용자의 ID 정보가 담긴 문자열 배열 report, 정지 기준이 되는 신고 횟수 k가 매개변수로 주어질 때, 각 유저별로 처리 결과 메일을 받은 횟수를 배열에 담아 return 하도록 solution 함수를 완성해주세요.

 

제한사항

  • 2 ≤ id_list의 길이 ≤ 1,000
    • 1 ≤ id_list의 원소 길이 ≤ 10
    • id_list의 원소는 이용자의 id를 나타내는 문자열이며 알파벳 소문자로만 이루어져 있습니다.
    • id_list에는 같은 아이디가 중복해서 들어있지 않습니다.
  • 1 ≤ report의 길이 ≤ 200,000
    • 3 ≤ report의 원소 길이 ≤ 21
    • report의 원소는 "이용자id 신고한id"형태의 문자열입니다.
    • 예를 들어 "muzi frodo"의 경우 "muzi"가 "frodo"를 신고했다는 의미입니다.
    • id는 알파벳 소문자로만 이루어져 있습니다.
    • 이용자id와 신고한id는 공백(스페이스)하나로 구분되어 있습니다.
    • 자기 자신을 신고하는 경우는 없습니다.
  • 1 ≤ k ≤ 200, k는 자연수입니다.
  • return 하는 배열은 id_list에 담긴 id 순서대로 각 유저가 받은 결과 메일 수를 담으면 됩니다.
  • 2 ≤ id_list의 길이 ≤ 1,000
    • 1 ≤ id_list의 원소 길이 ≤ 10
    • id_list의 원소는 이용자의 id를 나타내는 문자열이며 알파벳 소문자로만 이루어져 있습니다.
    • id_list에는 같은 아이디가 중복해서 들어있지 않습니다.
  • 1 ≤ report의 길이 ≤ 200,000
    • 3 ≤ report의 원소 길이 ≤ 21
    • report의 원소는 "이용자id 신고한id"형태의 문자열입니다.
    • 예를 들어 "muzi frodo"의 경우 "muzi"가 "frodo"를 신고했다는 의미입니다.
    • id는 알파벳 소문자로만 이루어져 있습니다.
    • 이용자id와 신고한id는 공백(스페이스)하나로 구분되어 있습니다.
    • 자기 자신을 신고하는 경우는 없습니다.
  • 1 ≤ k ≤ 200, k는 자연수입니다.
  • return 하는 배열은 id_list에 담긴 id 순서대로 각 유저가 받은 결과 메일 수를 담으면 됩니다.

 

발상

신고 결과를 취합하고 -> 결과를 집계해서 정지여부를 판단하고 -> 신고한 사람들에게 피드백을 주는 문제이다.

1차 자료를 가공하고 가공된 자료를 활용하여 다시 2차 결과물을 만드는데, 약간 복잡했다.

1차원의 ID 리스트를 상관계수 표처럼 2차원을 확장하고, 확장한 y축을 신고결과를 누적하게 한 뒤, 취합하면 나중에 전체순회를 여러번 하지 않고 편하게 자료를 활용할 수 있을 것 같아서 2차원 배열로 구현하였다.

의사코드

1. 초기값 선언(2차원 배열)
2. 신고 결과 배열 마킹{
	1. 신고자 배열위치 확인(스트림 인덱스)
    2. 피신고자 배열위치 확인
    3. 보드에 마킹(0일 때만 1)
}
3. 신고 결과 취합 및 정지여부 판단
4. 정지대상과 신고자 체크 후 결과값 반환

 

코드

더보기
public int[] solution(String[] id_list, String[] report, int k) {

    /*
     * 처리결과 횟수를 배열로 받음
     * nxn 배열로 확대하고, 주어진 배열 그대로의 인덱스를 사용함
     * 신고한 결과를 나중에 스트림으로 필터링하고 리턴하면 됨
     * */
    int[] reportResult = new int[id_list.length];
    int[][] reportBoard = new int[id_list.length][id_list.length];
    for (String s : report) {
        String[] reportTicket = s.split(" ");
        int reporter = IntStream.range(0, id_list.length)
                .filter(f -> reportTicket[1].equals(id_list[f]))
                .findFirst()
                .orElse(-1);
        int reportee = IntStream.range(0, id_list.length)
                .filter(f -> reportTicket[0].equals(id_list[f]))
                .findFirst()
                .orElse(-1);
        reportBoard[reporter][reportee]=1;
    }
    for (int i = 0; i < id_list.length; i++) {
        for (int j = 0; j < id_list.length; j++) {
            reportResult[i] += (reportBoard[i][j] >= 1) ? 1 : 0;
        }
    }
    for (int[] ints : reportBoard) {
        for (int anInt : ints) {
            System.out.print(anInt + ", ");
        }
        System.out.println();
    }
    System.out.println("=================================");
    int[] answer = new int[id_list.length];
    for (int i = 0; i < reportBoard.length; i++) {
        if(Arrays.stream(reportBoard[i]).sum()>=k){
            for (int j = 0; j < reportBoard.length; j++) {
                answer[j] += reportBoard[i][j] >= 1 ? 1 : 0;
            }
        }
    }

    return answer;
}

 

개선

여러 과정을 거쳐서 자료를 가공해야 하고, 방법도 굉장히 많은 방법이 있어 보여서 고민하는데 시간이 많이 걸렸다.

하지만 가장 빠른 방법은 바로 구현할 수 있는 방법이고, 너무 많은 시간을 고민에 쓰지말고 어느정도 전략이 세워지면 구현을 해야 한다.

진행하다 보면 문제점이나 개선점이 보이게 되니 일단 구현해보는 것이 좋은 것 같다.

'IT > Algorithm' 카테고리의 다른 글

[programmers] 전화번호 목록  (0) 2022.08.18
[programmers] 기능 개발  (0) 2022.07.27
[programmers] 로또의 최고 순위와 최저 순위  (0) 2022.07.17
[programmers] [1차] 비밀지도  (0) 2022.07.17
[Algorithm] RSA 암호  (0) 2022.07.17

Vector, Hashtable 및 StringBuffer와 같은 Java API의 초기 클래스는 thread-safe하게 동기화되어 있다.

하지만 단일 스레드에서 사용하는 경우에도 동기화를 하게 되므로 성능에 큰 부정적인 영향을 끼친다.

따라서 싱글 스레드 상황에서는 동기화되지 않는 다른 대체클래스를 사용하는 것이 좋다.

  • Vector 대신 ArrayList 또는 LinkedList
  • Stack 대신 Deque
  • Hashtable 대신 HashMap
  • StringBuffer 대신 StringBuilder

 

비준수 코드 예

 

Vector cats = new Vector();

 

준수 솔루션

 

ArrayList cats = new ArrayList();

 

 

참고자료

 

SonarLint

https://sonarcloud.io/organizations/default/rules?languages=java&open=java%3AS1149&q=S1149 

 

SonarCloud

██████╗ ██╗ ██╗████████╗██████╗ █████╗ ████████╗███████╗██████╗ ██████╗ ██████╗ ██████╗ ██

sonarcloud.io

Java:S1149

https://school.programmers.co.kr/learn/courses/30/lessons/77484

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제

Lotto ball

로또 6/45(이하 '로또'로 표기)는 1부터 45까지의 숫자 중 6개를 찍어서 맞히는 대표적인 복권입니다. 아래는 로또의 순위를 정하는 방식입니다. 1

순위당첨 내용
1 6개 번호가 모두 일치
2 5개 번호가 일치
3 4개 번호가 일치
4 3개 번호가 일치
5 2개 번호가 일치
6(낙첨) 그 외

로또를 구매한 민우는 당첨 번호 발표일을 학수고대하고 있었습니다. 하지만, 민우의 동생이 로또에 낙서를 하여, 일부 번호를 알아볼 수 없게 되었습니다. 당첨 번호 발표 후, 민우는 자신이 구매했던 로또로 당첨이 가능했던 최고 순위와 최저 순위를 알아보고 싶어 졌습니다.
알아볼 수 없는 번호를 0으로 표기하기로 하고, 민우가 구매한 로또 번호 6개가 44, 1, 0, 0, 31 25라고 가정해보겠습니다. 당첨 번호 6개가 31, 10, 45, 1, 6, 19라면, 당첨 가능한 최고 순위와 최저 순위의 한 예는 아래와 같습니다.

당첨 번호3110451619결과
최고 순위 번호 31 0→10 44 1 0→6 25 4개 번호 일치, 3등
최저 순위 번호 31 0→11 44 1 0→7 25 2개 번호 일치, 5등
  • 순서와 상관없이, 구매한 로또에 당첨 번호와 일치하는 번호가 있으면 맞힌 걸로 인정됩니다.
  • 알아볼 수 없는 두 개의 번호를 각각 10, 6이라고 가정하면 3등에 당첨될 수 있습니다.
    • 3등을 만드는 다른 방법들도 존재합니다. 하지만, 2등 이상으로 만드는 것은 불가능합니다.
  • 알아볼 수 없는 두 개의 번호를 각각 11, 7이라고 가정하면 5등에 당첨될 수 있습니다.
    • 5등을 만드는 다른 방법들도 존재합니다. 하지만, 6등(낙첨)으로 만드는 것은 불가능합니다.

민우가 구매한 로또 번호를 담은 배열 lottos, 당첨 번호를 담은 배열 win_nums가 매개변수로 주어집니다. 이때, 당첨 가능한 최고 순위와 최저 순위를 차례대로 배열에 담아서 return 하도록 solution 함수를 완성해주세요.

제한사항

  • lottos는 길이 6인 정수 배열입니다.
  • lottos의 모든 원소는 0 이상 45 이하인 정수입니다.
    • 0은 알아볼 수 없는 숫자를 의미합니다.
    • 0을 제외한 다른 숫자들은 lottos에 2개 이상 담겨있지 않습니다.
    • lottos의 원소들은 정렬되어 있지 않을 수도 있습니다.
  • win_nums은 길이 6인 정수 배열입니다.
  • win_nums의 모든 원소는 1 이상 45 이하인 정수입니다.
    • win_nums에는 같은 숫자가 2개 이상 담겨있지 않습니다.
    • win_nums의 원소들은 정렬되어 있지 않을 수도 있습니다.

발상

요약하면 0으로 나눈 번호들을 모두 맞다고 가정한 순위와 모두 틀렸다고 가정한 순위를 구하여 반환하는 문제이다.

두 배열을 비교하여 일치한 번호를 세야 하고 0인 번호들을 세서 순위를 구해야 한다.

의사코드

1. 0인 번호 구하기
2. 일치하지 않는 번호 구하기
3. 순위를 만들어 반환

 

개선

스트림을 이용하여 나름대로 filter 안에 다시 다른 배열을 스트림으로 받아 비교하여서 읽기 쉬운 코드를 작성하였다고 생각하였다.

하지만 결국 순위를 구하는 로직이 후에 추가적으로 작성되어야 했고, 순위의 예외처리도 필요하여 코드가 복잡해졌었다.

다른사람의 풀이를 보니, 결과값을 만들 새로운 스트림을 기존의 배열이 아닌 초기선언 방식으로 선언해두고, 그 위치에 스트림을 이용하여 순위값을 만들어 넣었다.

그뒤 체이닝을 통해 순위로직을 처리하여 return 함수 한줄에 코드가 모두 정리되는 것을 확인했다.

 

스트림이 알고리즘과 코딩테스트에선 성능이슈가 큰 부분이 확실히 존재하지만, 익숙해진다면 빠르게 구현할 수 있기 때문에 여러 문제를 풀어야 하는 코딩테스트 상황에서 다른 문제에 더 시간을 집중하고, 나중에 다 푼 뒤에 최적화가 가능한 장점이 있다.

또한 코딩테스트만을 위한 최적화가 아닌 실제 업무에서는 읽기 좋은 유지보수하기 좋은 코드가 더 선호되기 때문에 성능이슈에도 불구하고 스트림을 계속 사용하는 것이 충분히 합리적이라 생각한다.

'IT > Algorithm' 카테고리의 다른 글

[programmers] 기능 개발  (0) 2022.07.27
[programmers] 신고 결과 받기  (0) 2022.07.26
[programmers] [1차] 비밀지도  (0) 2022.07.17
[Algorithm] RSA 암호  (0) 2022.07.17
[programmers] 시저암호  (0) 2022.07.14

+ Recent posts