집 컴퓨터로 개발을 해본지가 참 오래 됐다

오랜만에 실행하려고 하니 아래와 같은 에러가! 두둔!

 

 

A Java Runtime Envitonment (JRE) or Java Development Kit (JDK) must be available in onder to run Eclipse. No Java virtual machine was found after searching the following locations : C:\Program Files\Java\jdk1.8.0_151\jre\bin

 

문자그대로 해석해보면 이클립스를 실행하기 위해서는 JRE와 JDK가 반드시 있어야 하는데 내 컴퓨터에서 찾을 수 없다는 뜻이다. 보통 ①안깔려있거나 ②경로지정을 잘못해줬을때 뜬다.

 

 

먼저 환경변수를 확인 해 본다. 환경변수가 뭔지 잘 모른다면 아래 글을 참고하자.

출처 : 삐멜 소프트웨어 엔지니어 블로그

 

 

환경변수에 문제가 없는데도 계속 실행이 안된다면 이클립스의 시스템설정을 확인해 보자. 이클립스가 설치된 경로에 가서 eclipse.ini 파일을 실행하면 된다.

 

열어보니 시스템파일에 경로가 잘못 설정되어 있었다. JRE 설치 경로를 제대로 바꿔주고 저장한뒤 다시 이클립스를 실행하면 정상 작동한다!

 

'개발툴설치하기' 카테고리의 다른 글

인텔리제이(IntelliJ) 설치하기  (1) 2019.02.25

 

 

<폰 싸게사는법 시리즈>1편 호갱 안당하는법(클릭)2편 자급제폰과 알뜰요금제(현재글)

 

 

1편에서는 호갱이 되지 않기 위한 기본적인 용어설명과 SK/KT/LG 3대 통신사 휴대폰 싸게 사는법을 다루었다. 2편에서는 자급제폰&알뜰통신사의 조합으로 좀더 저렴하게 이용하는 법에 대해 설명하겠다.

 

 

 

단말기 자급제란?

휴대폰 구입은 전문 판매점에서, 개통은 이통사 대리점에서 각각 따로 하는 제도

 

 

핸드폰이 갑자기 고장나서 공기계에 유심카드만 꽂아서 써본 경험이 있는가? 그게 바로 자급제이다. 휴대폰요금제를 패키지로 구매하는게 아니라 단말기는 사용자가 자급자족하고 요금제는 전혀 별개로 선택하도록 하는 방법이다. 약정 기간이 없어 요금제 사용이 자유롭고 알뜰통신사를 이용하면 통신비를 더욱 아낄 수 있다. 자급제 전용 폰으로 나오는 기기들도 있지만 꼭 자급제폰이 아니더라도 어떤 경로든 통신사 약정 없이 공기계를 구할 수 있다면 이용 가능한 방법이다.

 

 

아이폰11을 구매한다고 해보자. 계산의 편의상 아이폰11의 기기값이 100만원이라고 하자.(애플 공홈에서 99만원)

이동통신3사에서 구매하는 경우 아이폰11의 공시지원금은 10만원이 채 되지 않으므로 선택약정으로 구매하는것이 유리하다. (이 말이 무슨말인지 잘 모르겠다면 1편을 보고오자)

 

 

데이터 양이 정확히 똑같은 요금제가 없어서 비슷한 요금제로 골랐다.

SK의 뉴 T끼리 맞춤형(데이터 월 6GB)에 선택약정 25%를 적용해서 월 37,331원인데 헬로모바일의 보편 유심 5GB 요금제를 이용하면 월 24,950원, 심지어 지금은 프로모션 기간이라 월 13,840원에 이용 가능하다. 매달 12,318원 씩 차이가 나고 2년동안 대략 30만원정도를 아낄 수 있다.

 

 

그리고 대부분 잘 모르고 넘어가는 것이 있는데 통신사에서 할부로 휴대폰을 구매하면 할부이자 5.9%가 붙는다. 예를 들어 100만원짜리짜리 2년간 납부하는 총액은 대략 106만원이 조금 넘는다. 자급제로 공기계 구입시 카드 무이자할부 혜택등을 이용하면 할부이자를 내 않아도 된다. 

 

 

 

 

 

자급제폰으로 알뜰통신사 이용하기

공기계는 공홈이나, 쿠팡, 11번가 등에서 구입하면 되고 개통은 각 알뜰통신사 홈페이지에서 신청하면 집으로 유심카드를 보내 준다. 신청 과정은 어렵지 않으니 생략한다. 가입버튼을 누른 후 주소지와 요금제 납부방식 등등을 시키는대로 입력하면 된다.

 

 

1 공기계 구입하기

 

아이폰 12 mini 자급제폰 (클릭시 구매링크 이동)

 

 

갤럭시21 울트라 자급제폰 (클릭시 구매링크 이동)

 

 

 

갤럭시 폴드 자급제폰 (클릭시 구매링크 이동)

 

파트너스 활동을 통해 일정액의 수수료를 제공받을 수 있음

 

2 알뜰통신사에서 유심 신청하기

 

헬로모바일

http://direct.lghellovision.net/

 

 

SK텔링크

https://www.sk7mobile.com/

 

 

 

 

 

알뜰통신사를 이용하기 전 알아두어야 할 점이 있다. 알뜰통신사의 일부 요금제는 사용가능한 휴대폰 기종이 정해져 있는 경우도 있다(웬만한 기종은 됨). 신청 전 한번 확인해보자. 그리고 알뜰통신사는 가족결합 할인 등은 안된다. 온가족이 합쳐 SK를 30년 이상 사용했다 이런 경우에는 쓰던 통신사를 그대로 유지하는게 나을 때도 있다. 해지 전 현재 받고있는 혜택과 비교해보고 고르자.

 

 

 

 


LeetCode 문제 중 난이도 EasyImplement Queue using Stacks이다. 문제 링크는 포스팅의 맨 마지막에 추가하였다. 언어는 Java를 사용했다.




  문제해석


스택의 오퍼레이션을 이용하여 큐의 다음 오퍼레이션들을 구현하라.

push(x) -- 큐의 마지막에 x를 삽입

pop() -- 큐의 맨앞의 요소를 제거

peek() -- 맨앞의 요소를 가져옴

empty() -- 큐가 비었는지 여부를 리턴


스택(Stack)은 LIFO(Last-In, First-Out), 큐(Queue)는 FIFO(First-In, First-Out)의 구조를 가졌다. 스택과 큐를 잘 모른다면 아래 포스팅을 참고한다. 


스택&큐 Stack and Queue



스택으로 큐를 구현하려면, ① 넣을때부터 FIFO로 넣던지 ② 넣을때는 LIFO로 넣고 꺼낼때 FIFO로 꺼내면 된다.


① FIFO처럼 저장하는 방법은 마지막으로 넣는 요소를 스택의 가장 아래(bottom)에 저장하는 것이다. 그러면 스택에서 꺼낼때, 먼저 저장된 요소가 먼저 꺼내진다(FIFO). 코드로 나타내면 아래와 같다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class MyQueue {
 
    Stack<Integer> myqueue = new Stack<Integer>();
 
    public MyQueue() {
        
    }
 
    public void push(int x) {
        Stack<Integer> temp = new Stack<Integer>();
 
        //myqueue에 있는 요소들을 temp으로 옮겨담는다
        while(!myqueue.isEmpty()){
            temp.push(myqueue.pop());
        }
        //temp의 맨 위에 x를 삽입한다
        temp.push(x);
        
        //myqueue에 다시 옮겨담는다(가장 마지막에 넣은 x가 temp의 가장 아래로 가게됨)
        while(!temp.isEmpty()){
            myqueue.push(temp.pop());
        }
    }
    
    public int pop() {
        return myqueue.pop();
    }
 
    public int peek() {
        return myqueue.peek();
    }
    
    public boolean empty() {
        return myqueue.isEmpty();
    }
}
cs


 넣을때는 LIFO로 넣고 꺼낼때 FIFO처럼 꺼내는 방법은 저장할때는 그냥 스택의 맨 위(top)에 저장한다. 꺼낼때에는 스택의 맨 마지막에 있는 요소를 불러온다. 코드로 나타내면 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class MyQueue {
 
    Stack<Integer> myqueue = new Stack<Integer>();
    
    public MyQueue() {
        
    }
    
    public void push(int x) {
        myqueue.push(x);
        
    }
 
    public int pop() {
        Stack<Integer> temp = new Stack<Integer>();
        
        //myqueue의 요소들을 전부 temp에 옮겨담는다
        while(!myqueue.isEmpty()){
            temp.push(myqueue.pop());
        }
        
        //temp의 가장 위에있는 요소를 꺼낸다
        int top = temp.pop();
        
        //원래대로 myqueue에 옮겨담는다
        while(!temp.isEmpty()){
            myqueue.push(temp.pop());
        }
        return top;
    }
    
    public int peek() {
        Stack<Integer> temp = new Stack<Integer>();
        
        while(!myqueue.isEmpty()){
            temp.push(myqueue.pop());
        }
        
        int top = temp.peek();
        
        while(!temp.isEmpty()){
            myqueue.push(temp.pop());
        }
        return top;
    }
    
    public boolean empty() {
        return myqueue.isEmpty();
    }
}
cs




스택이란?

한쪽 끝에서만 데이터를 삽입/삭제 할 수 있는 선형 자료구조

LIFO(Last In First Out)의 특징을 가졌다.





스택 오퍼레이션

isEmpty() : 스택이 현재 비어있는지 체크

push(data) : 스택에 데이터 삽입

pop() : 스택에서 데이터 삭제

peek() : 스택의 맨 위(다음에 꺼낼 데이터) 확인





스택 구조





스택 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import java.util.EmptyStackException;
 
public class Stack {
    
    private static class Node {
        private int data;
        private Node next;
        private Node(int data) {
            this.data = data;
        }
    }
    
    private Node top;
    
    public boolean isEmpty() {
        return top == null;
    }
    
    public int peek() {
        if(isEmpty()) throw new EmptyStackException();
 
        return top.data;
    }
    
    public void push(int data) {
        Node node = new Node(data);
        node.next = top;
        top = node;
    }
    
    public int pop() {
        if(isEmpty()) throw new EmptyStackException();
        
        int data = top.data;
        top = top.next;
        return data;
    }
}
cs





큐란?

한쪽에서는 데이터 삽입만, 반대쪽에서는 데이터삭제만 가능한 선형 자료구조

FIFO(First In First Out)의 특징을 가졌다.





큐 오퍼레이션

isEmpty() : 큐가 현재 비어있는지 체크

enqueue() : 큐에 데이터 삽입

dequeue() : 큐에서 데이터 삭제

peek() : 큐의 맨 앞(다음에 꺼낼 데이터) 확인





큐 구조









































큐 구현

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import java.util.EmptyStackException;
 
public class Queue {
    
    private static class Node{
        private int data;
        private Node next;
        private Node(int data) {
            this.data = data;
        }
    }
    
    private Node front;
    private Node rear;
    
    public boolean isEmpty() {
        return front == null;
    }
    
    public int peek() {
        return front.data;
    }
    
    public void enqueue(int data) {
        Node node = new Node(data);
        if(rear != null) {
            rear.next = node;
        }
        rear = node;
        if(front == null) {
            front = node;
        }
    }
    
    public int dequeue() {
        if(isEmpty()) throw new EmptyStackException();
        
        int data = front.data;
        front = front.next;
        if(front == null) {
            rear = null;
        }
        return data;
    }
}
cs


'자료구조' 카테고리의 다른 글

해시테이블이란? Hash Table 구현 Java  (0) 2019.10.27
링크드리스트(Linked List) 구현 Java  (0) 2019.10.26


1 신청기간

- 온라인 : 3.30 ~ 5/15 (선착순 아님)

- 주민센터내방은 4.16 ~ 5부제적용(신청인기준)

- 찾아가는 접수는 거동이 어려운 사람에 한해서 날짜를 지정해서 직원이 방문함



2. 지원대상

20.03.18 00시기준~ 신청일까지 서울에 거주하는 사람 중 중위 소득 100%이내 가구

- 4대보험 적용 근로자의 경우 원천징수로 조회되는 소득 기준

- 프리랜서는 3개월 급여명세서 또는 소득신고서 제출

- 백수 : 소득신고서 0원 신고


3. 지원불가대상

- 수급자/차상위계층 : 4월에 별도로 상품권 지급 예정

- 아동수당 받는 가구

- 2020년도 실업급여 수급자

- 청년수당수급자

가구원중에 한명이라도 위의 해당사항이 있는 경우는 지원 불가(기타관계인/동거인인 경우 상관없음)



4 지급방식

모바일 지역상품권(제로페이 가맹점에서만 6월말까지 사용가능)





FAQ


Q 실거주는 서울, 주민등록은 경기도인데 지원받을수 있나요?

A 서울에 실거주 하더라도 재난 긴급생활비 지원 대책 발표일(3월 18일) 기준

 주민등록지가 서울시로 되어있고, 신청일 기준으로도 주민등록지가 서울시로

 되어있어야 지원이 가능합니다.


Q. 본인이 지급대상인지 어떻게 확인하나요?

A. 기준 중위 소득표와 제외대상을 확인 후 본인이 지원대상에 해당되는지 각 가정에 배부되는 전단지 및 서울시와 자치구 홈페이지를 확인하여 자가진단을 해보고, 신청하실 때 120 다산콜센터와 동 주민센터에 추가상담을 받으시면 됩니다. 소득계산은 가구원 모두의 세전소득액을 합산하여야 합니다.



Q. 재난긴급생활비 지원은 근로자만 받을 수 있나요?

A. 근로 여부와 상관없이 중위소득 100% 이하에 해당하면 지원합니다



Q. 한주소 세대주 분리의 경우 각각 지원 가능한가요?

A. 한 주소지 내 세대주가 분리되어 있어도 각각의 가구로 인정하여 지원가능합니다



Q. 국민기초생활수급(생계, 의료, 주거, 교육급여) 대상자는 재난긴급생활비를 지원받지 못하나요?

A.국민기초생활수급자는 정부로부터 지원받는 정책이 있기 때문에 서울시 재난    긴급생활비와 중복하여 신청할 수 없습니다.



Q. 신청하고 타시도로 이사갈 경우 지원받을수 있나요?

A. 접수통지를 받은 때까지 주민등록상 현재 서울시 거주의 경우 지원이 가능합니다.    (단, 재난 긴급생활비 지원 대책 발표일(3월 18일) 기준부터 서울시 거주)


Q. 중위소득 100% 이하 가구는 어떻게 알 수 있나요?

A. 중위소득 100% 기준표는 다음과 같습니다.




Q. 어떤 서류가 필요한가요?

A. 서울복지포털(http://wiss.seoul.go.kr)에서 서울시 재난 긴급생활비 지원 신청서와 개인정보 제공동의서를 다운받아 작성해주시면 됩니다. ※ 단, 온라인 신청 시 개인정보제공동의서만 다운받아 작성하여 업로드해주시면 됩니다.) 다만, 보건복지부 사회보장통합정보시스템을 통해 조회된 소득과 실제 소득이 다른 경우에는 추가 서류를 요청드릴 수 있습니다. 



Q. 4대 보험료를 낸 적도 없고 짧은 기간동안 일하여 소득신고가 된 적이 없는 경우 지원받을 수 있나요?

A. 사회보장정보시스템 상 확인되는 소득이 없으며, 소득 기준에 적합할 경우, 지원 가능합니다.



Q. 서울사랑상품권, 선불카드 신청 후 변경이 가능한가요?

A. 서울사랑상품권 및 선불카드는 소상공인 지원 및 지역상권   활성화를 위해 한시적으로 발행된 카드로 신청 후 변경·잔액환급이 불가능합니다



Q. 가구원 전체에 대한 개인정보 동의가 왜 필요한가요?

A.가구원 전체의 소득을 조회하기 위해서는 가구원의 개인정보제공에 대한 동의가 필수이며, 가구원 중 한명이라도 개인정보제공 동의 거부 시 지원할 수 없습니다.



Q. 가구당 1명만 신청 가능한가요?
A. 가구 단위로 1명만 신청 가능하며,  세대주 및 세대원 중 누구나 신청할 수 있습니다. 대리인의 경우 신분증, 관련서류, 위임장을 지참하여 동주민센터를 방문하면 됩니다.



Q. 재난긴급생활비를 지원받고 나서 타 제도의 지원을 받게되면 어떻게 되나요?

A. 서울시 재난 긴급생활비는 코로나19로 인해 생계가 어려운 가구에 대해 지원하므로, 재난긴급생활비를 지원 받은 후 새로운 위기상황이 발생하는 경우 타 제도의 지원을 받을 수 있습니다.



Q. 서울사랑상품권(모바일)과 선불카드를 6월말까지 사용해야 하는 이유는 무엇인가요?

A. 현 코로나19 사태로 인해 저소득층 근로자, 영세 자영업자 등이 생계위기에 직면해 있을 뿐만 아니라 마트·편의점 아르바이트 등 불안정한 일자리의 노동자에 대한 고용 감소까지 이어지고 있어 상반기 내 조속한 집행을 통해 지역 상권을 활성화하기 위함입니다.



Q. 외국인 및 난민도 지원되나요?

A. 다음의 조건에 모두 해당하는 외국인인 경우 지원합니다.

1) 출입국관리법 제31조에 따라 외국인 등록을 한 사람 

2) 서울시에 주소지를 둔 사람 

3) 대한민국 국적을 가진 사람과 혼인 또는 직계존비속 관계에 있는 사람

1), 2) ,3) 모두 해당하여야 함




직장인이라면 누구나 매년 해야 하는 연말정산이란 무엇이고 근로소득세를 절감할 수 있는 방법을 알아보자.




1 연말정산이란?

근로자들이 올해 납부한 근로소득세를 정산하는 절차로서, 원천징수의무자(회사)는 다음 연도 2월 분의 급여를 지급할 때에 매월 급여 지급 시 이미 원천징수한 세액이 세법에 따라 정확하게 계산한 연간 근로소득세 보다 많은 경우 많이 낸 세금은 돌려주고, 적게 낸 경우에는 추가 징수하여 납부하는 절차

쉽게 말해 우리가 1년 동안 냈던 세금과 실제 내야 할 정확한 세금을 비교해서 이미 낸 금액이 더 많다면 차액을 돌려(환급)주고 그 반대라면 추가로 걷어가는(추징) 것이다.





2 원천징수란?

소득금액 또는 수익금액을 지급하는자(원천징수의무자)가, 그 지급을 받는 자(원천납세의무자)가 부담할 세액을 정부 대신 징수하는 방식

원천징수의무자는 회사라고 보면 되고 원천납세의무자는 직장인들이다. 근로소득세는 연간 과세표준금액에 구간별 세율을 곱하여 계산한다. 그런데 매달 월급을 받을 때마다 이를 정확하게 계산해서 내기는 어렵다. 그래서 회사에서 각자 연봉에 비례하게 일정액을 걷어서 세금을 대신 납부해준다. 이를 통해 국가는 세금이 누락되는 것을 방지하고, 세금 수입을 조기에 확보할 수 있다. 또한, 납세의무자 입장에서는 세금을 1년에 한번 크게 내는 것보다 매달 분할 납부함으로써 조세 부담이 줄어든다. 



3 연말정산을 하는 이유

월급에서 매달 원천징수하는 그 세금의 금액이 정확하지 않기 때문이다. 연봉계약서에 정해지지 않은 보너스를 받을 수도 있고, 중간에 이직/퇴직 등으로 급여가 변동 될 수 있다. 근로자가 1년동안 얼마를 벌지 모르니 연말에 1년간 벌고 쓴 금액에 맞추어 세금을 다시 계산한다. 그리고 원천징수에는 개인마다 다른 공제혜택이 적용되지 않았다. 그래서 연말에 한 해 소득을 정산한 후 공제할 부분은 공제 한 후 최종 세금을 계산하는 연말정산을 하는 것이다.





4 과세표준이란?

소득에 대한 세액을 산정하기 위한 기초 단위

같은 연봉을 받는 직장인이라도 같은 금액의 세금을 내는것은 아니다. 나라에서 세금을 부과하는 개인별 표준금액이 있다. 이것을 과세표준 이라고 한다. 연간근로소득은 말 그대로 내가 벌어 들인 총 금액이고 과세표준은 그 중에서 비과세소득과 각종 소득공제분을 제외한 후 세금납부의 대상이 되는 금액이다.



예를 들어 내 연봉이 4000만원인데 각종 소득공제와 비과세소득을 제외하고 과세표준 금액이 2500만원이라고 하자. 즉 4000만원이 아닌 2500만원에 세금을 매기는 것이다. 당연히 과세표준액이 적으면 적을 수록 내가 내는 세금이 줄어든다. 과세표준에 따른 산출세액 계산법은 아래 표를 기준으로 한다. 한가지 확인해야 할 점은 세율은 누진적용이라는 것이다. 1201만원을 버는 사람은 1200만원에 대한 15%의 세금을 내는것이 아니라 1200만원까지는 6%의 세금을 내고 초과한 1만원에 대해서만 15% 세율이 적용된다. 아래 간편법으로 계산하면 편하다.(사실 근데 이걸 내가 직접 계산할 일은 없다 직장인이라면 회사에서 다 해줌)




5 소득공제와 세액공제 차이?

 

돈을 벌러 직장에 다니기 위해서 식비/교통비/의류구입비 등 필수적으로 지출해야 하는 돈이 일정부분 존재한다. 돈을 벌기위해 쓴 돈은 소득이라고 보기 어렵다. 그리고 우리가 돈을 벌어서 쓰는 소비활동은 나라 경제가 활성화 되는데 도움이 된다. 그래서 연간근로소득 중 내가 소비한 금액의 일부분 만큼 과세대상에서 제외해준다. 이것을 소득공제라고 한다.


세액공제는 말그대로 내가 내야 할 세금을 줄여주는 것이다. 아래 그림을 참고하면 쉽다. 과세표준에 세율을 곱해 산출세액을 계산하여 나온 세금에 세액공제/감면분을 제외하면 최종적으로 계산된 세금(결정세액)이 나온다.







여기까지 읽었다면 어떻게 해야 세금을 적게 낼 수 있는지 대충 감이 올 것이다. 소득공제금액과 세액공제금액이 많으면 많을수록 좋다.


소득공제와 세액공제 항목들에는 어떤것들이 있고 혜택을 최대한 많이 받는 법에 대해서는 2편에서 자세히 설명하겠다.





해시테이블이란?

데이터의 키값을 해시함수를 이용해 인덱스화하고 배열의 해당인덱스에 데이터를 저장하는 자료구조







해시테이블 구조






해시함수는 해당 데이터를 배열의 몇번째 인덱스에 저장할 것인지 정해주는 함수이다. 이름과 연락처를 해시테이블에 저장하고 이름의 첫 번째 글자가 알파벳의 몇 번째 문자인지로 배열의 인덱스를 정하는 해시함수를 사용해보자. 예를 들어 Ann은 첫번째(index=0), Becca는 두번째(index=1)에 저장한다.




해시테이블 충돌해결 방식 (Collision Resolution)

서로 다른 데이터도 같은 인덱스값을 가질 수 있다. 예를 들어 위의 해시테이블에 Rachel의 전화번호를 삽입해보자. Rachel과 Racine 둘다 알파벳 첫글자가 r이기 때문에 인덱스 18을 가질 것이다. 이럴 경우에 충돌이 많이 발생하면 속도가 느려진다. 아무리 좋은 해시 함수라도 해시함수에 인덱스 충돌이 아예 안생기기란 거의 불가능하다(배열을 아주 크게 만들면 충돌이 거의 발생하지 않지만 당연히 메모리 낭비가 심하다 관심이 있다면 Birthday Paradox를 검색해봐라). 가장 많이 알려진 해결법 두가지를 알아 보자.




Linear Probing(선형 탐사)

데이터를 삽입할 때 해당 인덱스에 이미 데이터가 존재하면 그 다음 인덱스(+n)로 이동하는 방식이다. 위의 예시에 대입해 보자. Rachel은 원래 18번째 위치에 저장되어야 하는데 그자리에 이미 데이터가 있으므로 +1을 한다. 19번째에도 데이터가 있으므로 +1을 해주어 20번째에 저장한다. 이 상태에서 Tina의 연락처를 저장한다면 데이터는 21번째에 삽입될 것이다.






Chaining(체이닝)

체이닝은 중복된 인덱스값을 갖는 데이터들을 연결(chain)하는 것이다. 각 인덱스에 링크드리스트로 연결한다.




해시테이블 장단점


장점

데이터를 검색할 때 고유의 인덱스값으로 접근하기때문에 검색속도가 매우 빠르다.


단점

테이블내의 여유공간이 많아야 성능이 유지되기 때문에 저장공간을 상대적으로 많이 사용한다.





해시테이블 구현


아래 코드는 체이닝 해시테이블로 위의 예시를 구현한 것이다. 먼저 이름(key)과 연락처(value)를 가진 연락처(Contact) 클래스로 링크드리스트를 만든다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Contact {
    private String key;        //name
    private String value;     //phone number
    public Contact(String key, String value) {
        this.key = key;
        this.value = value;
    }
    public String getKey() {
        return key;
    }
    public void setKey(String key) {
        this.key = key;
    }
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}
cs




이름의 첫 문자의 알파벳 순서대로 인덱스를 지정하고 같은 알파벳 때문에 충돌이 생기면 링크드리스트의 맨 뒤에 삽입한다. 연락처 검색시에는 키값을 이용해 해당인덱스의 링크드리스트를 순서대로 탐색한다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
import java.util.LinkedList;
 
public class ChainingHashTable {
    
    public LinkedList<Contact>[] data;
    
    public ChainingHashTable(int size) {
        data = new LinkedList[size];
    }
 
    int getHashCode(String key) {
        int hashCode = key.charAt(0)-'a';
        return hashCode;
    }
    
    int convertToIndex(int hashCode) {
        return hashCode % 26;
    }
    
    public void put(String key, String value) {
        
        int hashCode = getHashCode(key);
        int index = convertToIndex(hashCode);
        Contact contact = new Contact(key,value);
        if(data[index] == null) {
            data[index] = new LinkedList();
        }
        data[index].addLast(contact);
    }
    
    public String get(String key) {
        
        int hashCode = getHashCode(key);
        int index = convertToIndex(hashCode);
        LinkedList<Contact> contacts = data[index];
        for(Contact c : contacts) {
            if(c.getKey().equals(key)) {
                return c.getValue();
            }
        }
        return null;
    }
}
cs


'자료구조' 카테고리의 다른 글

스택&큐 Stack and Queue 구현 java  (0) 2020.04.19
링크드리스트(Linked List) 구현 Java  (0) 2019.10.26



링크드리스트란?

데이터가 연속한 공간에 저장되는것이 아닌, 데이터와 다음 데이터로의 링크를 가진 노드들이 연결된 선형 데이터구조 





링크드리스트 구조




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class LinkedList {
    
    Node head;
}
 
public class Node {
    
    Node next;
    String data;
    
    public Node(String data) {
        this.data = data;
    }
    
}
cs





링크드리스트 장단점


장점

배열처럼 처음부터 크기가 고정되는게 아니라 동적할당을 하기 때문에 선언시 크기를 지정하지 않아도 되어 메모리를 효율적으로 사용할 수 있다.

데이터의 추가/삭제가 용이하다.


단점

배열은 데이터를 찾을 때 인덱스로 접근하고 링크드리스트는 처음부터 순차적으로 접근한다. 그래서 k번째 데이터를 조작할 때 시간이 O(n)으로 오래 걸린다.



링크드리스트 구현


링크드리스트의 오퍼레이션들을 직접 구현해보자. 먼저 아래와 같은 링크드리스트 맨 앞에 데이터를 삽입하는것을 생각해보자.



순서는 다음과 같을 것이다.


1 노드 생성

2 1에서 만든 노드의 링크를 기존 링크드리스트의 head로 연결

3 링크드리스트의 head를 1에서 만든 노드로 변경


그림으로 보면 이해가 더 쉽다.


코드로 구현하면 다음과 같다.


1
2
3
4
5
6
7
8
9
public void addFirst(String data) {
    if(head == null) {
        head = new Node(data);
        return;
    }
    Node newHead = new Node(data);
    newHead.next = head;
    head = newHead;
}
cs



이번엔 링크드리스트의 마지막 값을 삭제해보자.


1 현재노드를 링크드리스트의 head로 지정

2 현재노드를 다음노드로 변경

3 다음노드를 가리키는 링크가 없을때까지 2를 반복

4 현재노드의 이전노드의 링크 삭제


previous : 이전노드 / current : 현재노드



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void removeLast() {
    if(head == null) {
        return;
    }
    if(head.next == null) {
        head = null;
        return;
    }
    Node current = head;
    Node previous = null;
    while(current.next != null) {
        previous = current;
    }
    current = current.next;
    previous.next = null;
}
cs




처음값 삭제, 특정 값 삭제 등도 구현해보자.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
public class LinkedList {
    
    Node head;
    
    public void addFirst(String data) {
        if(head == null) {
            head = new Node(data);
            return;
        }
        Node newHead = new Node(data);
        newHead.next = head;
        head = newHead;
    }
    
    public void addLast(String data) {
        if(head == null) {
            head = new Node(data);
            return;
        }
        Node current = head;
        while(current.next != null) {
            current = current.next;
        }
        current.next = new Node(data);
    }
    
    public void removeFirst() {
        if(head == null) {
            return;
        }
        head = head.next;
    }
    
    public void removeLast() {
        if(head == null) {
            return;
        }
        if(head.next == null) {
            head = null;
            return;
        }
        Node current = head;
        Node previous = null;
        while(current.next != null) {
            previous = current;
        }
        current = current.next;
        previous.next = null;
    }
    
    public void removeValue(String data) {
        if(head == null) {
            return;
        }
        if(head.data.equals(data)) {
            head = head.next;
            return;
        }
        Node current = head;
        while(current.next != null) {
            if(current.next.data.equals(data)) {
                current.next = current.next.next;
                return;
            }
            current = current.next;
        }
    }
}
cs


'자료구조' 카테고리의 다른 글

스택&큐 Stack and Queue 구현 java  (0) 2020.04.19
해시테이블이란? Hash Table 구현 Java  (0) 2019.10.27



<보험 호갱 안되는법 시리즈>

· 보험 가입시 유의사항 1편(클릭)

· 보험 가입시 유의사항 2편(현재글)

· 보험 가입시 유의사항 3편(예정)



1탄에서 보험은 나에게 필요한 보장을 조합해서 설계해야 한다는 얘기를 했다. 아직 안읽었다면 위의 링크에서 보고 오시라..

보험에 가입하려고 상품을 알아보다 보면 모든 경우를 다 보장해주었으면 좋겠고 보험금도 많이 나왔으면 좋겠다는 생각을 한다. 설계사가 이 특약은 안넣으면 손해라며 부추기면 팔랑팔랑 넘어가버리기도 한다. 당연히 보장도 더 많이 해주면서 보험료도 저렴하면 좋겠지만 그런보험은 없다. 고객이 낸 보험료에 비해 자주 보험금이 지급되는 보장은 보험사 입장에서는 손해이다. 보험사는 매년 손해율을 계산하고 해당 보장의 보험료를 올리거나 없애버린다.



암보험에 암만 포함되는 게 아니라 보통 6대질병/8대질병 등으로 각종암+뇌관련+심혈관 질환에 대한 보장을 묶어서 판매한다. 이글에서는 편의상 전부 암보험이라고 칭하겠다.



2탄을 이해하기 위한 용어들을 먼저 보고 가자.


진단비 : 특정 질병에 걸렸다고 진단받으면 수술이나 치료 여부에 상관 없이 보험사가 나에게 즉시 지급해주는 보험금

수술비 : 암 진단 확정 후, 암 치료를 목적으로 수술을 받으면 지급된다

치료비 : 암 진단 확정 후, 암 치료를 목적으로 방사선,항암,약물 등의 치료를 받을 때 지급되는 금액

입원비 : 암 진단 확정 후, 암 치료를 목적으로 입원했을 때 지급되는 입원 1일당 금액

부담보 : 피보험자의 과거 병력이나 특정 질환에 대해 일정 기간 각종 보장에서 제외해 조건부로 가입하는것

청약철회 : 보험 가입 후 30일 이내에는 낸 보험료를 전액 돌려받고 취소 가능



한가지 유의해야 할점은 진단비는 내가 암이라고 진단을 받기만 하면 나오는 보험금이다. 하지만 수술비, 치료비, 입원비 등은 다르다. 극단적인 예로 암을 발견했는데 말기라서 손도 쓰지 못한채 사망했다. 그러면 받지 못하는 돈이다. 보통 '암의 직접치료 목적으로 ~하면 지급' 이런식으로 써놓는데, 암치료를 위한 목적으로 하는 수술을 받았을 경우에만 해당한다. 그리고 신기술을 이용한 수술(예를 들면 로봇을 이용한 최신 수술법)은 인정이 안되는 경우도 있다. 확실히 보험료를 받기 위해서는 암 진단금을 높이고 수술비나 치료비 입원비 등은 상황에 따라 받지 못할수도 있다는 점을 염두하자.


수술비는 암수술비 보다는 일반수술비(질병에 상관없이 수술하면 보험금 지급, 1~5종 등으로 분류) 특약을 넣는 것이 낫다.


입원비특약은 추천하지 않는다. 보통 며칠 이상 입원시 n일째부터 조건이 붙어 있는 경우도 있고 요즘은 입원을 길게 시키는 추세가 아니라 입원일당은 내가 낸 보험료에 비해 타먹을 일이 많지 않다.



그럼 암에 걸리기만 하면 진단금이 나올까? 아니다. 어떤 암들은 사망률이 매우 낮고 수술도 굉장히 간단한 경우(예:제자리암)가 있다. 이런 암들을 보험사에서는 '소액암'으로 분류한다. 갑상선암,생식기암,기타피부암,유방암 등이 여기에 해당한다. 보험사별로 소액암의 분류가 약간씩 다르다.


보험사는 아픈 고객을 싫어한다. 보험금을 지급할 확률이 높으니 당연한 이치이다. 보험 가입 전 병력이 있다면 그부분은 일정기간동안/또는 영원히 보장해주지 않는 조건으로 보험을 가입시켜 준다. 예를 들어 자궁근종으로 수술을 받은 이력이 있어 자궁 부위가 부담보로 정해졌다면 피보험자가 자궁 부위에서 질병이 발생해도 보험회사가 정한 기간(1~5년) 동안 보상받지 못하는 것이다.



보험 약관을 보면 '보험 가입후 91일 이후에 보장' 등의 문구를 보게 된다. 오늘 암보험에 가입했는데 내일 암진단을 받았다고 보험금을 받을 수 있는 건 아니다. 만일 그렇다면 사람들이 몸이 이상하다 싶으면 보험에 가입하고 병원에 갔다가 이상이 없으면 청약철회를 할 것이다.




아래는 내가 보험에 가입할 때 따르는 순서이다. 


1 암 진단금을 설정한다. 내 연봉이 실수령액으로 3000만원 정도 된다고 치자. 내가 만약에 중대한 병에 걸려서 1년동안 일을 쉬어야 한다고 치면 3000만원의 기회비용이 생긴다. 암보험이 없어도 수술하는데 든 병원비는 실비에서 어느정도 보장받을 수 있다. 하지만 1년동안 돈을 벌지 못하더라도 적금,공과금 등 소비는 멈출수가 없다. 진단금은 암에 걸렸을 때 내 생계유지를 위한 보험이다. 보통 3~5000만원 정도로 설정하고 연봉에 따라, 부양가족 여부 등에 따라 적절하게 조절하면 된다.


2 꼭 보장받아야겠다 싶은 병을 체크한다. 기본적으로 6대질병/8대질병 등으로 암·뇌·심장에 관한 보장들을 묶어서 판매하긴 하나, 그중에서 내가 가장 걱정되는 부분이 있을 것이다. 보험사별로 보장범위나 진단금이 다르다.  주로 생명보험사에서는 뇌출혈만, 손해보험사에서는 뇌혈관질환(더 넓은 범위)를 보장한다.

예를 들어 나는 직계 가족중에 유방암 진단자가 2명이나 있다. 뇌 관련질환은 한명도 없다. 그럼 나는 뇌 관련 보장이 더 넓은 보험보다는 유방암을 일반암으로 보장해주거나 유방암특약조건이 좋은 보험사를 선택할 것이다. (물론 둘다 최고로 보장해주면 좋지만 위에서 말했듯이.. 전부다 보장해주면서 보험료가 저렴한 보험은 없다^^)


3 위의 1&2에서 정한 조건을 가지고 최소 2명 이상의 설계사와 상담한다. 친구나 직장 동료에게 보험 들었으면 설계사 소개시켜달라고 하면 시켜준다. 한명의 설계사에게 상담받고 바로 가입하지는 말자. 적어도 2명 이상은 상담해보자.



만약에 보험이 아예 없는데 암에 걸렸다. 그러면 돈이 없어 치료로 못 하는가??


아니다. 정부에서 일정부분 의료비를 지원해준다. 자세한 내용은 아래 링크에서 확인 해라.

http://www.ncc.re.kr/main.ncc?uri=manage01_5





이 포스팅이 도움이 되었다면 아래 공감♡ 버튼을 누르자.


LeetCode 문제 중 난이도 MediumMinimum Add to Make Parentheses Valid이다. 문제 링크는 포스팅의 맨 마지막에 추가하였다. 언어는 Java를 사용했다.





  문제해석

'('와 ')'로 이루어진 문자열 S에 최소로 괄호기호를 더해서 결과값이 유효하게 만든다.

유효한 괄호 문자열이란

- 빈 문자열 이거나,

- A와 B가 각각 유효한 괄호 문자열일때 AB를 연결한 형태이거나,

- A가 유효한 문자열일때 (A)의 형태인것


유효한 괄호문자열로 만들기 위해서 추가해주어야 할 최소한의 괄호기호의 개수를 구하여라.






스택(Stack) 자료구조를 이용해서 문제를 해결해보자. 스택은 FILO(First In Last Out)의 특징을 가진 자료구조이다. 책을 겹겹이 쌓는것을 상상해보자. 맨 위에 책을 올려놓거나 맨 위에 있는 책을 치울 수 있다. 아래에 있는 책을 꺼내려면 먼저 그 위의 책들을 전부 치워야 한다.





push(value) : value를 스택의 마지막 데이터 위치에 삽입

pop() : 스택 마지막 삽입된 데이터 제거

peek() : 스택 마지막 삽입된 데이터 값 확인





문제에서 괄호가 제대로 열리고 닫히려면

1 괄호를 연만큼 닫아주어야 한다. → '('와 ')'의 갯수가 같아야 함

2 먼저 열어준 뒤에 닫아주어야 한다. → '))(('은 유효한 괄호문자열이 아님



문자열 S를 탐색하면서 i번째 문자가 '('이면 스택에 넣어주자. i번째 문자가 ')'인 경우 스택에 들어있는 '('문자를 제거해준다. 스택이 비어있어서 제거할 '('가 없다면 answer+1을 해주자. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
    public int minAddToMakeValid(String S) {
        
        Stack<Character> stack = new Stack<>();
        int answer=0;
        
        for(int i=0 ; i<S.length() ; i++){
            if(S.charAt(i)=='('){
                stack.push(S.charAt(i));
            }else if(stack.empty()){
                result++;
            }else{
                stack.pop();
            }
        }
        
        return answer + stack.size();
    }
}
cs


answer는 필요한 '('의 개수이고 stack에 들어있는 '('만큼 ')'도 필요하다. 따라서 answer+stack.size()가 유효한 괄호문자열을 만들기 위해 필요한 '('와 ')'의 개수이다. 이 방법의 시간복잡도는 O(n), 공간복잡도는 O(n)이다.


문제출처 - https://leetcode.com/problems/minimum-add-to-make-parentheses-valid/

+ Recent posts