SWE_python_Stack2

1.Stack

목차

  1. 계산기에서의 Stack 활용
  2. 백트래킹
  3. 분할정복

1.1 계산기

  1. 중위표기법의 수식을 후위표기법으로 변경
    • 스택 이용
    • 중위표기법 : 연산자를 가운데로 표기하는 방법
  2. 후위표기법의 수식을 스택을 이용하여 계산
    • 후위표기법 : 연산자를 피연산자 뒤에 표기하는 방법

1.2 중위표기식을 후위표기식을 변환하는 방법

No Image

중위 표기식을 후위표기식으로 변환 알고리즘

  1. 입력 받은 중위표기식에서 토큰을 읽음
  2. 토큰이 피연산자이면 토큰을 출력
  3. 토큰이 연산자(괄호 포함)일 경우
    • 우선순위가 높으면 -> 스택에 push
    • 우선순위가 안 높으면 -> 연산자의 우선순위가 토큰의 우선순위보다 작을 때까지 스택에서 pop한 후 토큰의 연산자를 push
    • 만약 top에 연산자가 없으면 push No Image No Image

예시 중위표기법으로 표현된 수식

No Image No Image No Image 이 과정을 동영상을 보면 이해가 간다.

후위표기법을 수식의 스택을 이용하여 계산

  1. 피연산자를 만나면 스택에 Push함
  2. 연산자를 만나면 필요한만큼 스택에서 pop하여 연산하고, 연산결과를 다시 스택에 push함
  3. 수식이 끝나면, 마지막으로 스택을 pop하여 출력

계산 시 주의사항 ! : 후위표기식을 계산 시, 피연산자를 스택에 쌓아 계산! No Image 이 때, 연산자의 순서에 주의해야 한다. 처음에 pop한 값을 연산자 오른쪽으로, 그 다음에 pop한 값을 연산자의 왼쪽에 넣고 계산을 수행해야 한다.

문자열로 된 수식을 계산 시

스택을 두 번 사용해서 처리했던 연산을 파이썬에서 제공되는 eval() 내장 함수로 계산할 수 있다.

eva(수식)

  • 문자열로된 수식을 계산함
  • Evaluation = “값을 구함:이란 뜻
  • 올바른 수식이 아닌 경우 SyntaxError 예외가 발생함
  • eval(“6+5*(2-8)/2”)는 문자열로된 수식의 결과를 반환함

2. 백트래킹

해를 찾는 도중아 ‘막히면’, (즉, 해가 아니면) 되돌가서 다시 해를 찾아가는 기법 -> 최적화 문제와 결정 문제를 해결할 수 있다.

결정문제 : 문제의 조건을 만족하는 해가 존재하는 지의 여부를 ‘yes’ 또는 ‘no’로 답하는 문제

  • 미로 찾기 문제
  • n-Queen 문제
  • Map coloring
  • 부분 집합의 합(Subset Sum)문제 등

2.1 백트레킹 기법 활용 - 미로 찾기

  1. 입구와 출구가 주어진 미로에서 입구부터 출구까지의 경로를 찾는 문제
  2. 이동할 수 있는 방향은 4방향으로 제한 No Image

백트래킹 기법 활용 - 미로 찾기 알고리즘 1

  1. 처음 위치에서 오른쪽으로 이동한 후 이동 상황을 스택에 푸시. 여기서 이동 방향은 시계 방향 혹은 반시계 방향으로 우선순위를 정할 수 있다. No Image
  2. 그림처럼 1,3처럼 다시 이동할 수 없을 때, 스택에 있던 이동상황을 pop하면서 뒤로 돌아간다.
  3. 1,1에서 아래쪽으로 이동이 가능하므로 스택에 이동경로를 저장하면서 다시 이동

2.2 백트래킹과 깊이 우선 탐색의 차이

백트래킹

  • 어떤 노드에서 출발하는 경로가 해결책으로 이어질 것 같지 않으면 더 이상 그 경로를 따라가지 않음으로써 시도의 횟수를 줄임
  • 가지치기(Prunning)
  • 불필요한 경로의 조기 차단
  • N! 가지의 경우의 수를 가진 문제에 대해서 백트래킹을 가하면 일반적으로 경우의 수가 줄어들지만 이 역시 최악의 경우에는 여전히 지수함수 시간(Exponential Time)을 요하므로 처리 불가능
  • 모든 후보를 검사하지 않음

깊이 우선 탐색

  • 모든 경로를 추적
  • N! 가지의 경우의 수를 가진 문제에 대해 깊이 우선 탐색을 가하면 처리 불가능한 문제
  • 모든 후보를 검사

2.3 백트래킹 기법

  • 어떤 노드의 유망성을 점검한 후에 유망하지 않다고 결정되면 그 노드의 부모로 되돌아가(Backtracking) 다음 자식 노드로 감
  • 여기서 유망성이란, 어떤 노드를 방문하였을 때 그 노드를 포함한 경로가 해답이 될 수 없으면 그 노드는 유망하지 않다고 함
  • 반대로 해답의 가능성이 있으면 유망하다고 함
  • 가지치기(Pruning): 유망하지 않은 노드가 포함되는 경로는 더 이상 고려하지 않음

2.4 백트래킹을 이용한 알고리즘의 절차

  1. 상태 공간 Tree의 깊이 우선 검색을 실시
  2. 각 노드가 유망한지를 점검
  3. 만익 그 노드가 유망하지 않으면, 그 부모의 부모 노드로 돌아가서 검색을 계속

2.5 일반 백트래킹 알고리즘 - n-Queen문제

n*n의 정사각형 안에 n개의 queen을 배치하는 문제로, 모든 queen은 자신의 일직선 상 및 대각선상에 아무것도 놓이지 않아야 함 No Image No Image

이를 상태공간 트리로 표시하면 다음과 같다.

No Image 깊이 우선 탐색보다 노드 수가 적다.

2.6 깊이 우선 검색 vs 백트래킹

순수한 깊이 우선 탐색 : 155노드 백트래킹 : 27노드 ㅈ

2.7 Power Set

  • 어떤 집합의 공집합과 자기자신을 포함한 모든 부분집합
  • 구하고자 하는 어떤 집합의 원소 개수가 n일 경우 부분집합의 개수는 2^n이 나옴
백트래킹 기법으로 Power Set 구하기
  1. 일반적인 백트래킹 접근방법 이용
  2. n개의 원소가 들어있는 집합의 2^n개의 부분집합을 만들 때, True 또는 False값을 가지는 항목들로 구성된 n개의 리스트를 만드는 방법을 이용
  3. 리스트의 i번째 항목은 i번째의 원소가 부분집합의 값인지 아닌지를 나타내는 값

2.8 Power Set을 구하는 백트래킹 알고리즘

No Image No Image 원하는 작업 도달이면 수행, 아니면 재귀호출 이 때, 백트래킹 하기 위한 후보군을 구하는 함수를 따로 구현. 후보군 구하는 함수에서는 해당 호출상태에서 추가로 구할 수 있는 후보군을 선정하여 반환한다. 영상에서 이부분 오래 설명함. No Image

2.9 순열을 구하는 백트래킹 알고리즘

후보군을 만드는 방법이 부분집합과 다르다. No Image No Image No Image No Image

3 분할정복

3.1 설계전략

나폴레옹 -> 아우스터리츠 전투에서 연합군을 공격하기 위해 엽한군을 둘로 나누고 둘로 나뉜 연합군을 한 부분씩 격파

  1. 분할 : 해결할 문제를 여러 개의 작은 부분으로 나눔
  2. 정복 : 나눈 작은 문제를 각각 해결
  3. 통합 : (필요하다면) 해결된 해답을 모음

3.2 거듭 제곱 알고리즘 O(n)

No Image

** 분할 정복 기반의 알고리즘 : O(log2n) ** No Image

3.3 퀵 정렬과 합병 정렬의 비교

합병정렬과 퀵 정렬의 공통점 : 주어진 리스트를 두 개로 분할하고, 각각을 정렬

차이점

  • 합병정렬 : 분할할 때, 단순하게 두 부분으로 나눔. 각 부분 정렬이 끝난 후 ‘합병’이란 후처리 작업이 필요함
  • 퀵정렬 : 분할할 때, 기준 아이템(Pivot Item)을 중심으로, 이보다 작은 것은 왼편, 큰 것은 오른편에 위치시킴. 각 부분 정렬이 끝난 후, 후처리 작업이 필요하지 않음

3.4 퀵 정렬 알고리즘

No Image No Image

3.5 퀵 정렬 수행 과정

이해안가면 영상 다시 보면서 이해하기

퀵 정렬의 최악의 시간 복잡도는 O(n^2) 그런데 왜 ? 퀵 정렬 ?

퀵 정렬의 평균 복잡도는 nlogn이기 때문이다. 평균적으로는 가장 빠르다.


참고자료 [SWE]https://swexpertacademy.com

0%