Sad Puppy 3 개발자 아지트 :: 개발자 아지트

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

 

프로그래머스

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

programmers.co.kr

문제설명

XYZ 마트는 일정한 금액을 지불하면 10일 동안 회원 자격을 부여합니다. XYZ 마트에서는 회원을 대상으로 매일 한 가지 제품을 할인하는 행사를 합니다. 할인하는 제품은 하루에 하나씩만 구매할 수 있습니다. 알뜰한 정현이는 자신이 원하는 제품과 수량이 할인하는 날짜와 10일 연속으로 일치할 경우에 맞춰서 회원가입을 하려 합니다.

 

예를 들어, 정현이가 원하는 제품이 바나나 3, 사과 2, 2, 돼지고기 2, 냄비 1개이며, XYZ 마트에서 14일간 회원을 대상으로 할인하는 제품이 날짜 순서대로 치킨, 사과, 사과, 바나나, , 사과, 돼지고기, 바나나, 돼지고기, , 냄비, 바나나, 사과, 바나나인 경우에 대해 알아봅시다. 첫째 날부터 열흘 간에는 냄비가 할인하지 않기 때문에 첫째 날에는 회원가입을 하지 않습니다. 둘째 날부터 열흘 간에는 바나나를 원하는 만큼 할인구매할 수 없기 때문에 둘째 날에도 회원가입을 하지 않습니다. 셋째 날, 넷째 날, 다섯째 날부터 각각 열흘은 원하는 제품과 수량이 일치하기 때문에 셋 중 하루에 회원가입을 하려 합니다.

 

정현이가 원하는 제품을 나타내는 문자열 배열 want와 정현이가 원하는 제품의 수량을 나타내는 정수 배열 number, XYZ 마트에서 할인하는 제품을 나타내는 문자열 배열 discount가 주어졌을 때, 회원등록시 정현이가 원하는 제품을 모두 할인 받을 수 있는 회원등록 날짜의 총 일수를 return 하는 solution 함수를 완성하시오. 가능한 날이 없으면 0 return 합니다.

 

문제 해결 방법

해시를 통해 문제를 해결함

 

코드 구현

def solution(want, number, discount):     
    hyeon = { }
    cnt = 0
    
    for i in want:
        if i in hyeon:
            continue
        else:
            hyeon[i] = number[cnt]; 
            cnt+=1
    
    total = len(discount)
    if total <= 10:
        cnt = 1
    else:
        cnt = total % 10
        cnt += 1
        if total>=20:
            cnt += ((total//10)-1)*10
    
    check = 0
    day = 0
    
    while(1):
        if cnt == 0:
            break
        
        ndiscount = []
        for i in range(check, check + 10):
            ndiscount.append(discount[i])
        
        disHash = {}
        
        for i in ndiscount:
            if i in disHash:
                disHash[i] += 1
            else:
                disHash[i] = 1
                
        if disHash == hyeon:
            day+=1
        
        cnt-=1
        check+=1
        
    return day

 

시간/공간 복잡도

O(N^2)

 

최적화 및 개선

따로 하지않음

 

어려웠던 점

discount의 원소들이 20개 이상 넘어가는 경우를 헤아리지 못했음 

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

 

프로그래머스

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

programmers.co.kr

문제설명

수많은 마라톤 선수들이 마라톤에 참여하였습니다. 단 한 명의 선수를 제외하고는 모든 선수가 마라톤을 완주하였습니다.

 

마라톤에 참여한 선수들의 이름이 담긴 배열 participant와 완주한 선수들의 이름이 담긴 배열 completion이 주어질 때, 완주하지 못한 선수의 이름을 return 하도록 solution 함수를 작성해주세요.

문제 해결 방법

해시는 딕셔너리로 구현하였다. 

코드 구현

def solution(participant, completion):
    # 참가 participant, 완주 completion
    p = { }
    
    for i in participant:
        if i in p: 
            p[i] += 1
        else:
            p[i] = 1
    
    for i in completion:
        if i in p:
            p[i] -= 1

    for key in p.keys():
        if p[key]> 0:
            return key

 

시간/공간 복잡도

O(N)

최적화 및 개선

따로 하지 않음

 

어려웠던 점

참 순전히 딕셔너리 제대로 쓸줄 몰라서 못푼 문제였다.. 

남의 코드를 보는것은 내 기준에서 80% 이상 도움되는 일이다.. 그동안 왜 고집부리면서 안봤는지..

지난 세월이 아쉽구만.. 

고루틴, 동시성 프로그래밍

 

 

고루틴은 경량화 된 스레드로서 컨텍스트 스위칭 비용이 발생하지 않는다. 

 

코어가 여러개인 멀티 코어 환경에서는 고루틴을 여러개 사용해 성능을 높일 수 있다. 

 

고루틴 여러개가 같은 메모리 영역을 조정할 경우, 예상치 못한 문제가 발생 가능하다. 

 

뮤텍스는 고루틴 하나만 동시에 자원에 접근할 수 있도록 조정한다. 

 

뮤텍스를 잘못 사용할 경우, 데드락에 문제가 발생할 수 있다. 

 

Go에서 뮤텍스 없이 동시성 프로그래밍을 하기 위해 작업 분할 방식 혹은 역할 분할 방식을 통해 작업할 수 있다. 

 

 

 

 

채널, 컨텍스트

 

채널은 고루틴 간의 메시지를 전달하는 메시지 큐이다. 

이를 통해 뮤텍스 없이도 동시성 프로그래밍이 가능하다.

 

동시성 프로그래밍에서 생산자와 소비자 패턴이 많이 사용되며, 이는 Go에서 채널을 이용해 구현 가능하다. 

 

컨텍스트란?

 

작업자에게 일을 지시할 때 사용하는 일종의 작업 명세서이다. 

이를 통해 특정 시간 동안만 작업을 지시하거나, 외부에서 작업 취소가 가능하다. 

 

만약 채널을 제때 닫지 않을 경우, 무한 대기를 지속하는 좀비 루틴이 발생되어 프로그램 성능을 떨어트리고 메모리 사용을 지속적으로 증가시키는 문제가 생길 수 있다. 

 

 

 

 

 

 

해당 글은 [Tucker의 Go 언어 프로그래밍] 24장~25장을 읽고 공부한 글입니다. 

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

 

프로그래머스

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

programmers.co.kr

 

문제설명

코니는 영어 단어가 적힌 카드 뭉치 두 개를 선물로 받았습니다. 코니는 다음과 같은 규칙으로 카드에 적힌 단어들을 사용해 원하는 순서의 단어 배열을 만들 수 있는지 알고 싶습니다.

 

원하는 카드 뭉치에서 카드를 순서대로 한 장씩 사용합니다.

한 번 사용한 카드는 다시 사용할 수 없습니다.

카드를 사용하지 않고 다음 카드로 넘어갈 수 없습니다.

기존에 주어진 카드 뭉치의 단어 순서는 바꿀 수 없습니다.

 

예를 들어 첫 번째 카드 뭉치에 순서대로 ["i", "drink", "water"], 두 번째 카드 뭉치에 순서대로 ["want", "to"]가 적혀있을 때 ["i", "want", "to", "drink", "water"] 순서의 단어 배열을 만들려고 한다면 첫 번째 카드 뭉치에서 "i"를 사용한 후 두 번째 카드 뭉치에서 "want" "to"를 사용하고 첫 번째 카드뭉치에 "drink" "water"를 차례대로 사용하면 원하는 순서의 단어 배열을 만들 수 있습니다.

 

문자열로 이루어진 배열 cards1, cards2와 원하는 단어 배열 goal이 매개변수로 주어질 때, cards1 cards2에 적힌 단어들로 goal를 만들 있다면 "Yes", 만들 수 없다면 "No" return하는 solution 함수를 완성해주세요.


문제 해결 방법

덱을 활용하여 문제를 해결함 


코드 구현

from collections import deque

def solution(cards1, cards2, goal):
    answer = ''
    
    cards1Q = deque()
    cards2Q = deque()
    
    for i in range(len(cards1)):
        cards1Q.append(cards1[i])
        
    for i in range(len(cards2)):
        cards2Q.append(cards2[i])
        
    cnt = 0
    check = 0
        
    while(1):
        check = 0
        
        if cnt >= len(goal):
            return "Yes"

        if len(cards1Q) != 0:
            if goal[cnt] == cards1Q[0]:
                cnt+=1
                check +=1
                cards1Q.popleft()

        if len(cards2Q) != 0:
            if goal[cnt] == cards2Q[0]:
                cnt+=1
                check +=1
                cards2Q.popleft()
                
        if check == 0:
            return "No"

    return answer

 

시간/공간 복잡도

O(N)

최적화 및 개선

따로 하지 않음

어려웠던 점

없음

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일 뒤에 이루어집니다.

문제 해결 방법

 

큐 구현을 위해 collections의 deque를 이용함

코드 구현

from collections import deque

def solution(progresses, speeds):
    answer = []
    
    progressesQ = deque()
    speedsQ = deque()

    cnt = 0
    
    for i in range(len(progresses)):
        progressesQ.append(progresses[i])
        speedsQ.append(speeds[i])

    while(1):
        
        if progressesQ[0]>=100:
            for i in range(len(progressesQ)):
                if progressesQ[i] >= 100:
                    cnt+=1
                else:
                    break
            
            answer.append(cnt)
            for i in range(cnt):
                progressesQ.popleft()
                speedsQ.popleft()
            cnt = 0
        
        if(len(progressesQ)==0):
            break

        
        for i in range(len(progressesQ)):
            progressesQ[i] += speedsQ[i]
    
    return answer

 

시간/공간 복잡도

O(N^2)


최적화 및 개선

파이썬 list의 pop()대신 deque의 popleft()를 사용함 


어려웠던 점

없음

자료구조

 

  • 배열
    • 원소마다 메모리가 연속적으로 할당되어 있다.
  • 리스트
    • 메모리 할당이 연속적이지 않다. 
    • 원소 추가 및 삭제의 시간복잡도는 O(1)로, 배열에 비해 처리가 빠르다. 
    • 시작과 끝이 연결되어 원형 구조를 이룬다. 
    • 키, 값의 쌍으로 이루어진 데이터 구조이다. 
    • 데이터를 빠르게 처리할 수 있다. 

 

 

에러 핸들링

 

Go에서는 Error 인터페이스를 통해 에러를 반환한다. 

 

에러는 errors.New() 혹은 fmt.Errorf()함수를 통해 만들 수 있다. 

사용자 정의 타입으로 Error()메서드를 정의해 error 객체를 만들 수 있다. 

 

에러를 감싸서 새로운 에러를 만들수도 있고(에러 랩핑),  감싸진 에러는 다시 풀어서 에러 처리를 할 수 있다. 

감싸진 에러를 다시 풀 때는 errors 패키지의 As()함수를 통해 사용한다. 

 

 

프로그램을 사용하다가 계속 사용하기 어려운 상황에 직면할 경우, 프로그램의 흐름을 중지시키는 기능을 패닉이라고 한다. 

Go에서는 프로그램을 즉시 종료할 때 내장함수인 panic()함수를 통해서 하고 복구는 recover() 함수를 통해 할 수 있다. 

 

 

 

 

 

 

해당 글은 [Tucker의 Go 언어 프로그래밍] 22장~23장을 읽고 공부한 글입니다. 

인터페이스

 

인터페이스란?

인터페이스는 자바의 클래스 비슷하지만 다른 개념임. 

메서드 구현도 가능하고 추상화된 객체로 사용가능함(인터페이스는 메서드의 집합체이다. )

객체지향 프로그래밍에서 가장 중요한 역할을 함.

인터페이스를 이용할 경우, 구체적인 객체가 아닌 인터페이스 만으로도 메서드를 호출할 수 있음.
따라서 프로그램 변경사항 발생시 유연하게 변경가능함.

 

 

인터페이스 사용법

// 타입 선언 키워드, 인터페이스 명, 인터페이스 선언 키워드, {} 내부에는 메서드 집합을 기입해줌

type MeInterface interface{
	Eat()
    Walk(distance int) int 
}

 

인터페이스도 구조체와 같이 타입중 하나임으로 type 키워드를 써준다. 

즉, 인터페이스 변수 선언 및 변수처럼 값으로 사용 가능하다. 

 

 

메서드 집합 사용시 유의사항 

type Tmp interface{
	String() string
    String(int) string // 메서드명을 중복되게 사용할 수 없음
    _(y int) // 메서드는 반드시 이름 필요함
}

 

 

인터페이스 사용 예시

package main
import "fmt"

type Stringer interface {
	String() string
}

type Student struct {
	Name string
    Age  int
}

func (s Student) String() string { 
// student 타입은 Stringer의 String() 메서드를 포함함 따라서, 
// Student타입은 Stringer 인터페이스로 사용될 수 있음

	return fmt.Sprintf("Hi My name is %s, my age is %d.", s.Name, s.Age)
    // Sprintf 함수는 문자열을 만들어 String타입의 값으로 반환하는 함수
}

func main(){
	student := Student{ "Minsoo", 101 }
    var stringer Stringer // stringer은 Stringer인터페이스임
    
    stringer = student 
    //stringer을 통해 Student타입의 student를 갖고 있음으로써 student의 메서드 String이 호출됨
    
    fmt.Printf("%s\n", stringer.String())  
}

 

출력값: Hi My name is Minsoo, my age is 101.

 

 

 

인터페이스에서 정의한 메서드 집합을 가진 모든 타입은 인터페이스로 쓰일 수 있다. 

 

덕 타이핑이란, 인터페이스에서 정의한 메서드 포함 여부로 판단하는 것이다. 

 

인터페이스를 통해 추상화 계층을 만들 수 있으며, 관계로 상호작용을 정의한다. 

 

모든 타입이 비어있는 인터페이스의 변수 값으로 사용될 수 있다. 

 

인터페이스 변환을 통해, 인터페이스 변수에 대해 구체화된 타입이나 또 다른 인터페이스로 변경 가능하다. 

 

 

 

 

 

 

 

해당 글은 [Tucker의 Go 언어 프로그래밍] 20장~21장을 읽고 공부한 글입니다. 

 

함수 고급

 

인수 타입 앞에 마침표 3개를 찍는 것을 통해 가변 인수를 표현한다. 

 

함수 종료 전 처리해야 하는 로직 수행을 위해 defer을 사용할 수 있다. 

 

함수를 변수 값으로 저장하기 위해 함수 타입 변수를 사용할 수 있다. 

 

쉽게 내부 상태를 갖는 함수 정의를 통해 함수 리터럴을 사용할 수 있다. 

자바에서는 큐 구현을 위해서 ArrayDeque를 많이 사용함. 

덱은 Double Ended Queue를 줄인 말로써, 양 끝에서 삽입 삭제를 가능토록 한 큐를 구현한 것이다. 

 

package Mar0308;

import java.util.Queue;
import java.util.ArrayDeque;


public class Test {	

	public static void main(String[] args) {
		
		// ArrayDeque으로 큐 구현
		Queue<Integer> queue = new ArrayDeque<>();
		
		// 큐에 데이터 추가 
		queue.add(1);
		queue.add(2);
		
		// 큐의 맨앞 데이터 제거 후 반환
		int first = queue.poll();
		System.out.println(first); // 1
		
	}

}

 

 

덱을 큐처럼 사용하는 코드 

package Mar0308;

import java.util.ArrayDeque;


public class Test {	

	public static void main(String[] args) {
		
		ArrayDeque<Integer> q = new ArrayDeque<>();
		
		q.addLast(1);
		q.addLast(2);
		
		// 큐의 맨 앞 데이터 제거 후 반환
		int first = q.pollFirst();
		System.out.println(first);
		
		
	}

}

 

데이터를 addFirst()로만 넣고, pollLast()로만 꺼내면 덱을 통해 스택을 구현할 수 있음

 

'Java > Java입문' 카테고리의 다른 글

반복문  (0) 2024.07.05
조건문  (0) 2024.07.05
연산자  (0) 2024.07.05
자바 자료구조 구현 - 배열, ArrayList(리스트)  (0) 2024.03.08
자바 필수 문법 정리  (0) 2024.03.08

https://school.programmers.co.kr/learn/courses/30/lessons/68644?language=java

 

프로그래머스

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

programmers.co.kr

 

문제설명

정수 배열 numbers가 주어집니다. numbers에서 서로 다른 인덱스에 있는 두 개의 수를 뽑아 더해서 만들 수 있는 모든 수를 배열에 오름차순으로 담아 return 하도록 solution 함수를 완성해주세요.


문제 해결 방법

 

주어진 배열에서 각각 다른인덱스의 요소를 뽑아서 합을 구한후 해쉬셋에 추가

해쉬셋을 사용하여 중복제거함


코드 구현

import java.util.HashSet;

class Solution {
    
    public static HashSet<Integer> set1 = new HashSet<Integer>();
    public int[] solution(int[] numbers) {
        int[] answer = {};
        
        for(int i = 0; i < numbers.length; i++){
            for(int j = 0; j< numbers.length; j++){
                if(i == j){
                    continue;
                }
                
                int sum = numbers[i] + numbers[j];
                set1.add(sum);
                
            }
        }
        
       return set1.stream().sorted().mapToInt(Integer::intValue).toArray();
        
        //해쉬셋을 stream으로 변환후, 오름차순으로 정렬한다. 
        // 그 후 set1의 Integer객체들을 int형으로 변환해주고, 배열로 변환한다. 
    }
}

시간/공간 복잡도

O(N^2)


최적화 및 개선

따로 하지않음


어려웠던 점

문법에 익숙하지 않은점

 

 

'CodingTest > solved - Java' 카테고리의 다른 글

[백준2667] 단지번호붙이기  (0) 2024.03.06
[백준2606] 바이러스  (0) 2024.03.05
[백준2178] 미로 탐색  (0) 2024.03.05
[백준1260] DFS와 BFS  (0) 2024.03.04

배열(배열 크기 정적 구현)

public class Test {	
	public static void main(String[] args) {
		
		int[] arr = {0, 0, 0};
		int[] arr = new int[3];
		
		// 두줄의 결과값이 동일하다. 	
        
        //관련 메소드 3가지 
        System.out.println(arr.length); // 1, ArrayList의 원소 개수를 반환하는 메소드 
		Arrays.sort(arr); // Array의 모든 데이터를 정렬
		// 정렬 대상외의 다른 인수를 추가하지 않으면 오름차순으로 정렬함, 
		// 특정 범위의 데이터만 정렬할 시, from, to 인덱스를 지정할 수 있음 
        
        // 배열의 모든 데이터를 String으로 반환하는 메서드
		System.out.println(Arrays.toString(arr)); 
        
	}
}

 

배열 사용시 시간 복잡도

*배열 데이터에 접근하기 위한 시간 복잡도는 O(1)

*배열에 데이터를 추가할 경우 

    1. 맨 뒤에 삽입할 경우 시간복잡도 : 맨 뒤에 임의 접근이 가능하고, 다른 데이터에 영향을 주지 않음, O(1)

    2. 맨 앞에 삽입할 경우 시간복잡도 : 기존 데이터들을 한칸씩 뒤로 미는 연산 필요함, 밀어야하는 데이터의 개수가 N이면,  O(N)

    3. 중간에 삽입할 경우 시간복잡도 : 삽입한 데이터 이후의 값들을 모두 한칸씩 뒤로 미는 연산 필요, 밀어야하는 데이터의 개수가 N이면,  O(N)

 

배열 사용시 고려할점 

임의 접근이 가능하여 빠르게 접근할 수 있지만, 이를 위해 충분한 메모리 공간이 필요함. 

배열의 중간이나 맨앞에 데이터 삽입이 많은지 확인해야함. 

 

ArrayList(배열 크기 동적 구현)

package Mar0308;

import java.util.ArrayList;
import java.util.Collections;

public class Test {	

	public static void main(String[] args) {
		
		ArrayList<Integer> list = new ArrayList<>();
		
		list.add(0); 
		list.add(1); // 리스트의 끝에 값 추가 
		
		
		// 다른 컬렉션을 통한 초기화 
		
		ArrayList<Integer> list2 = new ArrayList<Integer>(list);
		System.out.println(list2); //[0, 1]
		
		// 인덱스를 통한 접근
		System.out.println(list2.get(0)); // 0
		
		// 데이터 삭제
		list.remove(list.size() -1); // 마지막 데이터 삭제 
		System.out.println(list); // [0]
		
		// 관련 메소드 3가지 
		
		System.out.println(list.size()); // 1, ArrayList의 원소 개수를 반환하는 메소드 
		System.out.println(list.isEmpty()); // false, ArrayList에 저장된 데이터가 하나도 없는지 여부를 반환하는 메소드 
		Collections.sort(list); // ArrayList의 모든 데이터를 정렬
		// 정렬 대상외의 다른 인수를 추가하지 않으면 오름차순으로 정렬함, 
		// 특정 범위의 데이터만 정렬할 시, from, to 인덱스를 지정할 수 있음 
		System.out.println(list); 
		
	}

}

 

 

'Java > Java입문' 카테고리의 다른 글

반복문  (0) 2024.07.05
조건문  (0) 2024.07.05
연산자  (0) 2024.07.05
자바 자료구조 구현 - 큐, ArrayDeque  (0) 2024.03.08
자바 필수 문법 정리  (0) 2024.03.08

+ Recent posts