파이썬과 함께하는 자료구조 책과 더불어

인프런에서 자바 강의를 같이 듣기로 결정. 권오흠 강사님 강좌이다.

기존에 했던것을 복습 하고 다시 리마인드 한다는 생각으로 듣는 중



챕터3은 스택, 큐, 데크 구조를 설명한 챕터이다.


스택은 뒤로만 값이 들어오고 뒤로 나가며

큐는 앞으로 나가고 뒤로 들어오고

데크는 앞뒤 전부 다 되고..


문제는 보통 스택에서 많이 나왔다.

자바 컴파일러가 syntax에러를 찾는 원리 역시 스택이고

후위표기법 역시 스택이고... 


3.6 부터 3.11 까지는 모두 스택 경우의 수를 따지는 문제이다.

수기로 일일히 찾아해보는 것이 좋다.


3.17 괄호 짝맞추기 프로그램 작성

이는 기본 스택의 원리 + 컴파일러 문법에러 찾기 문제인데

이번엔 중괄호, 소괄호 두개를 구분해야 하는게 붙었다.


def test(lst):

 # { = 123 , } = 125, (  = 40, ) = 41

 # 따라서 짝이 맞다면 두 값의 차는 

 numlst = []

 for i in lst:

  num = ord(i);

  if num == 123 or num == 40:

   numlst.append(num)

  else:

   chnum = numlst.pop();

   k = chnum - num 

   if k != -2 or k != -1  :

    return 'false lst';

    

 if len(numlst) != 0:

  return 'no lst';

  

 return 'ok lst'


문자열로 바로 확인하는 방법이 아닌 아스키 코드값으로 확인하고 짝맞추는 경우엔 두 값의 차로 계산을 해봤다. 하지만 이 경우 ) } 이런식으로 바로 닫히는 괄호가 나오면 찾지를 못했다..


3.18 회문을 검사하는 프로그램 작성

회문이란 abba 이런식으로 문자가 짝지어지는 것을 뜻한다. 데칼코마니처럼

위에 괄호 맞추는 것과 같은 원리로 하면 된다.


def checkstr(str):

 lst = list(str)

 chenum = len(lst) / 2;

 elst = []

 for i in lst:

  if len(elst) == 0:

   elst.append(i)

   k = elst[-1];

  elif k == i:

   elst.pop();

   if len(elst) == 0:

    continue;

   else:

    k = elst[-1];

  elif k != i:

   elst.append(i)

   k = elst[-1];

 

 if len(elst) != 0 :

  return 'false str'

 

 return 'ok str'   


17, 18번 원리는 다음과 같다

일단 빈 스택 리스트에 값을 하나한 집어 넣다가 같은 문자가 왔을 경우 (또는 닫히는 같은 종류의 괄호가 올경우) pop으로 스택 리스트에서 제거 해준다.

이런식으로 끝까지 반복했다면 제일 마지막에는 빈 스택리스트가 나와야한다.

만약 무언가가 남아있다면 이는 짝이 없다는 것.


3.20 후위표기법의 식을 계산하는 프로그램 작성

우리가 보통 사용하는 식은 중위표기법이다

1 + 2 + 3 이렇게.. 보기도 좋다.

후위표기법이란 12+3+ 이렇게 표현한다


이러한 식을 계산 하는 것도

결국 빈 스택 리스트에 값을 넣되 만약 사칙연산이 들어오면 그 앞서 있던 두개의 값들을 계산 해주면 된다.(식은 기본적으로 2개의 숫자와 1개의 연산자로 구성되므로 가장 짧은 후위표기식도 최소 2개의 숫자가 저장되어야한다)


1 2 + 일 경우엔  (1+2 계산 한 값)을 다시 스택에 집어 넣는다.

이런식...


def reverse_(for_lst):

 lst = []

 for i in for_lst:

  if isinstance(i, int):

   lst.append(i);

  elif i == '+':

   k = lst.pop() + lst.pop();

   lst.append(k)

   continue;

  elif i == '-':

   k = lst.pop() - lst.pop();

   lst.append(k);

   continue;

  elif i == '*':

   k = lst.pop() * lst.pop();

   lst.append(k);

   continue;

  elif i == '/':

   k = lst.pop() // lst.pop();

   lst.append(k);

   continue;

   

 return lst


괄호인 경우 까지 생각 못했다...


3.23 오늘 생각했던 문제중 가장 뿌듯했기도 하면서 어려웠던 문제..

이거때문에 아래는 생각도 못했다. 얘도 역시 괄호 버젼은 풀지도 못했다.

문제는 중위표기법을 후위표기법으로 바꾸는 코드를 짜시오 이다.

1 + 2 + 3 을 12+3+ 이렇게 바꿔야한다.


크게 스택 리스트를 두개 만들어서 하나는 숫자, 하나는 연산자만 담게 한다.

여기서 연산자 리스트에 조건이 3개가 갈린다.


위의 1+2+3의 예시는 간단하지만

만약 1 + 2 * 3 이라면? 사칙연산 때문에 123*+ 가 된다.

즉 * , / 때문에 고민을 한번 더 해야한다.


그렇기에 만든 조건은 다음과 같다(feat 승완군..


0. +,- 와 *, / 를 서로 다른 가중치를 두어 구분한다.

나의 경우 +,- 는 1로, * , / 는 2로 구분지었다.

0. 항상 연산자 리스트에 있는 요소가 무엇인지 확인한다.

그리고 새로 들어오는 값을 비교한다


1. + 가 있을 경우에 +와 같은 가중치 값이 연산자 리스트로 들어온다면 

기존에 있던 +를 숫자 리스트로 보내버린 후 새 값을 연산자 리스트에 넣는다.


즉 1 + 2 - 3 의 경우

숫자 리스트 : 1,2

연산자 리스트 + 인 상황에서 -가 들어올때 1의 조건에 걸리므로

숫자: 1,2,+

연산자 : -

이렇게 저장이 된다.


2. +가 있을 경우에 + 보다 가중치 값이 큰 연산자가 들어온다면 연산자 리스트에 그대로 쌓는다.


즉 1 + 2 * 3 의 경우

숫자 : 1 2

연산자: + 인 상황에서 *가 들어와야 한다.

2의 조건에 걸리므로

숫자 : 1,2

연산자 : +, * 가 된다.


3. 만약 가중치가 작은 값이 새로 들어온다면? 즉 *, /가 있는 상황에서+, -가 들어온다면 기존에 있던 애들을 모두 숫자로 보낸 후 새로 들어오는 값을 연산자에 넣어준다.


즉 1+ 2 * 3 -4 인 경우

숫자: 12

연산자: +* 인 상황에서 - 가 들어와야 한다.

3의 조건에 걸리므로

숫자: 12*+(+,*를 pop()으로 뽑아서 *,+ 로 들어왔다)

연산자 - 가 된다


그리고 모두 다 돌아가면 연산자 리스트에 있는 애들을 전부 숫자로 옮겨주면 된다.


def make_for2(lst):

 chlst = {'+' : 1, '-': 1,'*':2, '/':2}

 str_lst = []

 op_lst = []

 for i in lst:

  if isinstance(i, int):

   str_lst.append(i)

   if i == lst[-1]: # 모두 다 돌아갔을때, 즉 마지막 값이 숫자일 경우를 뜻한다.

    num = len(op_lst)

    for n in range(num):

     str_lst.append(op_lst.pop())

   continue;

  else:

   if len(op_lst) == 0:

    op_lst.append(i);

   elif chlst[i] == chlst[op_lst[-1]]: # 키 값이 같으면

    str_lst.append(op_lst.pop())

    op_lst.append(i)

    continue;

   elif chlst[i] > chlst[op_lst[-1]]: # 새로 들어오는게 기존보다 크면

    op_lst.append(i) # 연산자 스택에 쌓는다

    continue;

   elif chlst[i] < chlst[op_lst[-1]]: # 새로 들어오는게 나보다 작으면

    # 새로 들어오는 것을 산술 스택에 쌓고 그 이전에 있던 애도 산술 스택에 쌓는다

    num = len(op_lst)

    for n in range(num):

     str_lst.append(op_lst.pop())

    op_lst.append(i);

 return str_lst;

 

물론 위 경우는 아직 괄호를 고려하지 않은 경우이다.

괄호 경우도 구상은 해놨는데 아직 코드화를 못했다.


스택 문제를 다 푼것은 아니지만 스택의 꽃은 후위표기법이라 생각한다.

생각보다 재밌다.





정보처리기사


예전에는 합격율이 엄청 높아서

문과 출신들도 쉽게 접근 가능한 자격증 중 하나였다고 함.


그래서 최근에는 이러한 이유 때문에 시험 방식이 

모두 주관식으로 바뀌고 여러 변화? 가 있었음...


그 결과 작년 17년, 합격율은 10% 언저리...


이번 시험은 작년 3회 시험이 너무 어려워서 그런지 좀 쉽게 낸 것 같다.

하지만 시험을 본 후 느낀점은 정보처리기사 보단 정보처리암기사 이며

합격율을 낮췄음에도 기사 자격증의 큰 의미를 못찾겠음. 

그렇기에 딴다고 해도 어떤 의미가 있을지 모르겠다.


0. 정보처리기사 실기는 총 5개의 과목을 본다.

알고리즘, 디비, 전산영어, 업무프로세스, 신기술용어

배점은 각기 다르다

다만 60점을 넘어야 합격을 하는데 알고리즘 + 디비 해도 50점 밖에 안되서

나머지 3과목을 공부하긴 해야한다.


1. 알고리즘

알고리즘은 크게 순서도 + 씨언어 + 자바 이렇게 나온다.

순서도의 경우 결과 값을 보여주고 이것이 진행되는 과정에 대해 순서도를 보여준 뒤

괄호를 뚫어서 그 안에 들어가는 알맞은 식을 적으면 된다.


씨언어, 자바의 경우 위와 동일 한데 순서도가 아닌 코드를 보여준다.

문제는 달팽이집, 90도 회전 같은 문제들이다.


둘다 막 어렵지는 않으며 실수만 조심하면 된다.

예를 들어 t++ 이냐 ++t냐 같은...


2. DB

쿼리문, 이론 등등 해서 복합적으로 나온다.

쿼리만 준비해서도 안되고 이론만 준비해서도 안되고...

이번엔 회복 관련 문제가 나와서 다들 많이 당황 한듯??

물론 나도 다틀림...


3,4 전산영어, 신기술

사실상 약어 많이 외우고 내가 아는 범위 내에서 나오길 기도해야한다.

다행히 1회차때는 생각보다 아는 단어가 많이 나왔다.

웃긴점은 신기술 같은 경우 약어 설명이 나오는데 모르겠으면 그냥 그대로 생각해서 쓰면된다.

예를들어 개방형 웹 서비스 플래폼? 이어었나 아무튼.. 이걸 묻는 문제였는데

개방 = Open / 웹 = Web / 서비스 = Service 등..

OWASP 이런식으로.. 구성이 되었다.

모른다고 그냥 넘어가지 말자


**tip 대충 외운 약어가 300개? 400개 좀 안되는거 같은데 생각보다 많지 않다.

나는 시험 3일전부터 이걸 달달 외웠다.

외우는 팁은

1. 해당 약어의 뜻을 그대로 이해하면 쉽다.

예를 들어 CSF : 성공에 중요한 요인을 찾아 결정하는 방법 이라는 뜻인데(요약)

Critical Success Factors , 이 단어들의 뜻을 합치면 결국 약어의 뜻이 된다.

이렇게 부분 나눠서 외우면 기억하기에 매우 좋다


2. 자주보자(누적학습법) 

고등학교때 영어단어 외울때도 썻던 방법인데, 외우는것은 결국 자주봐야 한다는 뜻이다.

3일 동안 약어 공부할때 뭘 공부하든 처음 10분은 약어를 전부 훑어봤다.

이런 방식으로 하면 3일동안 대충 10번씩은 볼 수 있다. 

또한 1부터 10번까지의 단어를 외운다고 할때

1번 보고, 2번보기전 다시 1번 보고, 3번보기전 다시 1,2번 보고 이런식으로 누적해서 약어들을 훑어보면 또 좋다.


5. 업무프로세스

지문 읽고 빈칸에 해당되는 내용 적으면 된다. 말그대로 업무에 필요한 내용들을 묻는건데 경영학과가 아니라서 이쪽이랑은 그렇게 친하지 않았다.

다만 여기에 공부할때 많은 시간을 투자하지는 않았다.

기출문제좀 읽어보는 정도?


5월 말에 결과 발표인데 합격이면 좋겠다.



## 합격했습니다


+ Recent posts