Python Code

def insert_sort(x):
    for i in range(1, len(x)):
        j = i - 1
        key = x[i]
        while x[j] > key and j >= 0:
            x[j+1] = x[j]  # 비교 값을 오른쪽으로 이동
            j = j - 1 # 앞쪽 값을 비교하기 위해 -1
        x[j+1] = key
    return x

 

삽입 정렬은 현재 값을 기준으로 앞쪽의 값들과 비교해 자기 자리에 삽입하는 정렬 알고리즘이다. 

삽입 정렬의 구체적인 알고리즘은 다음과 같다.

 

- 삽입 정렬은 두 번째 자료부터 알고리즘을 수행한다.

- 두 번째 자료(인덱스)부터 시작해 그 앞쪽의 값들과 비교해 삽입될 자리를 찾는다.

- 자리를 찾은 후 현재 값을 넣은 다음 나머지 값들은 한 칸씩 이동시킨다.(오른쪽)

- 세 번째 자료가 현재 값이 되고, 앞쪽 값인 첫 번째, 두 번째 값과 비교해 자리를 찾는다.

- 자리를 찾아 삽입되고 다른 값들은 옆으로 이동시킨다.

- 네 번째 값도 마찬가지로 왼쪽의 값들(1,2,3번째 값)과 비교해 삽입될 자리를 찾는다.

- 나머지 값들도 같은 방식으로 알고리즘이 수행된다.

 

 

위의 코드에서 보면 key가 선택된 값이 되고 j 인덱스가 왼쪽의 비교하는 값들이 된다.

j 번째 비교 값과 key 값을 비교했을 때 key가 작다면 j 번 값을 +1(즉 오른쪽으로 하나씩 이동) 시킨다. 계속 앞쪽의 값들과 비교해 비교 값들을 한 칸씩 오른쪽으로 이동시킨다.

만약 key 값이 더 크거나, 젤 앞의 값까지 비교가 끝나면 그 자리에 현재 값(key)을 넣어준다. 

 

 

삽입 정렬의 시간 복잡도

 

- 두 번째 값으로 시작 시 첫 번째 값과 비교 -- 1번

- 세 번째 값은 첫 번째, 두 번째랑 비교 -- 2번

- n-1 번째 값은 1, 2, 3,... , n-2 번째 비교 -- (n-2)번

- n 번째 값은 -- (n-1)번

 

즉, 1 + 2 + 3 + ... + n-2 + n-1 = n(n-1) /2 가 돼서, 시간 복잡도가 최악의 경우 O(n^2)가 된다. 최선의 경우는 자료가 다 정렬된 경우이고 이때는 시간 복잡도가 O(n)이 된다. 왜냐하면 각 자리의 값마다 왼쪽의 값 하나만 비교하면 되기 때문이다. 따라서 삽입 정렬은 n값이 커질수록 복잡도가 커져 알고리즘 성능이 떨어진다.

 

 

출처:위키피디아

 

반응형

 

 

1966번: 프린터 큐

문제 여러분도 알다시피 여러분의 프린터 기기는 여러분이 인쇄하고자 하는 문서를 인쇄 명령을 받은 ‘순서대로’, 즉 먼저 요청된 것을 먼저 인쇄한다. 여러 개의 문서가 쌓인다면 Queue 자료��

www.acmicpc.net

 

<내 코드>

case = int(input())
for _ in range(case):
	# n : 자료 개수 , m : 찾고자 하는 자료 위치
    n, m = map(int, input().split())
    imp = list(map(int, input().split()))
    temp = [0 for _ in range(n)] #리스트 표현식으로 0인 리스트 생성
    temp[m] = 1 # 찾고자 하는 m번째를 1로 표시
    cnt = 0

    while imp:
        if imp[0] == max(imp):
            cnt += 1
            if temp[0] == 1:
                print(cnt)
                break
            else:
                imp.pop(0)
                temp.pop(0)
        else:
            imp.append(imp[0])
            temp.append(temp[0])
            del(imp[0])
            del(temp[0])

 

- 중요도를 표시하는 imp 입력을 리스트로 만든다.

- imp 리스트와 비교하기 위한 temp 리스트를 만든다.

- imp[0]이 젤 큰 값인지 판단해, 아니라면 imp, temp 첫 요소를 뒤로 보내고 한 칸씩 땡긴다.

- imp[0]이 최댓값이면서 찾고자 하는 값이면 cnt 값을 출력하고 종료한다. 만약 찾고자 하는 값이 아니면 지우고 한 칸씩 땡긴다.

반응형

재귀 호출은 함수가 자기 자신을 다시 호출하는 것을 뜻한다. 알고리즘 공부에 있어서 중요한 개념이므로 확실하게 공부해야 한다. 재귀 호출에서 중요한 것이 반드시 '종료 조건'이 있어야 한다는 것이다. 만약 종료 조건이 없으면 무한루프에 빠지기 때문이다.

 

재귀 호출의 일반적인 형태

def func(입력):
	if 입력 값이 충분히 작으면: #종료 조건
    	return 결과
    ...
    func(더 작은 입력 값)  	# 더 작은 값으로 재귀 호출
    ...
    return 결과

 

재귀 호출의 세 가지 요건

  1. 함수 안에서 자기 자신을 다시 호출한다.
  2. 재귀 호출할 때 인자로 주어지는 입력 크기가 작아진다.
  3. 특정 종료 조건이 만족되면 재귀 호출을 종료한다. 즉, 종료 조건이 있어야 한다.

 

[예 제]

1. 1부터 n까지 더하기

def call_sum(n):
    if n <= 1:
        return n

    return n + call_sum(n-1)


print(call_sum(100))

함수 안에서 자기 자신을 계속해서 호출하는 방식으로 1부터 n까지 합을 구한다. 

 

 

2. 팩토리얼 구하기

def fact(n):
    if (n <= 1):
        return 1

    return n * fact(n-1)


print(fact(1))  # 1
print(fact(10))  # 10! = 3628800

종료 조건으로 n이 1과 같거나 작아지면 1을 리턴하게 해 마지막으로 1이 곱해지면서 결과를 리턴한다.

 

 

3. 최댓값 찾기

def find_max(nums, n):
    if n == 1:
        return nums[0]

    max_num = find_max(nums, n-1)

    if (max_num > nums[n-1]):
        return max_num
    else:
        return nums[n-1]


a = [17, 92, 18, 24, 35]
print(find_max(a, len(a)))  # 92

사실 리스트에서 최댓값, 최솟값을 구할 때 max(), min() 함수를 사용하면 쉽게 구할 수 있다.

반응형

사용한 언어: HTML, CSS, JavaScript(순수 JS)

프레임워크: 부트스트랩

 

 

- Numbers API

Numbers라는 재밌는 API를 이용해서 숫자에 맞는 재밌는 사실을 알려주는 웹앱을 만들어 봤다. 입력란에 아무 숫자나 넣으면 그 숫자에 맞는 사실(Fact) 한 가지를 보여주는 기능이다. 만약 숫자가 너무 크거나, 숫자에 맞는 리턴 값이 없다면 'boring number'라는 기본값을 보여준다.

 

 

Numbers API

NumbersAPI An API for interesting facts about numbers Bring meaning to your metrics and stories to your dates An API for interesting facts about numbers Bring your metrics and dates to life Let your metrics tell tales with our API of number facts What tale

numbersapi.com

 

- 결과

 

 

 

이 웹앱을 통해서 http통신을 요청하고 데이터를 받아오는 공부를 할 수 있었다. AJAX 와 Fetch api를 사용해 서버에 요청하고 데이터를 받아오는 방법을 사용했다. 디자인적인 요소는 부트스트랩을 이용해 빠르게 만들었다.

 

 

우선, HTML 코드는 다음과 같다. 

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Number Facts app</title>
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css"
      integrity="sha384-JcKb8q3iqJ61gNV9KGb8thSsNjpSL0n8PARn9HuZOnIxN0hoP+VmmDGMN5t9UJ0Z"
      crossorigin="anonymous"
    />

    <style>
      #fact {
        display: none;
      }
    </style>
  </head>
  <body class="bg-secondary">
    <div class="container">
      <div class="row">
        <div class="col-md-6 mx-auto">
          <div class="card bg-primary text-white p-4 mt-5">
            <h1>Number Facts</h1>
            <p>숫자를 입력하고 랜덤 Fact를 확인하세요.</p>
            <input
              type="number"
              id="numberInput"
              class="form-control form-control-lg"
              placeholder="숫자를 입력하세요.."
            />
            <div id="fact" class="card-body">
              <h4 class="card-title">
                Number Fact
              </h4>
              <p id="factText" class="card-text"></p>
            </div>
          </div>
        </div>
      </div>
    </div>
    <script src="main.js"></script>
  </body>
</html>

 

 

 

하나씩 설명하자면, 

<input
	type="number"
	id="numberInput"
	class="form-control form-control-lg"
	placeholder="숫자를 입력하세요.."
/>

<input> 태그는 숫자만 입력되도록 타입을 number로 설정했다. class는 부트스트랩 스타일링을 위해 다음과 같이 정했고, 자바스크립트에서 사용하기 위해 id값을 설정했다.

 

 

<div id="fact" class="card-body">
 <h4 class="card-title">
  Number Fact
 </h4>
 <p id="factText" class="card-text"></p>
</div>
#fact {
  display: none;
}

id가 fact인 숫자를 입력했을 때 값을 표현하는 영역이다. 우선 처음에는 이 영역을 display: none으로 설정해 보이지 않도록 했다. 그리고 나중에 값을 입력받았을 때, 자바스크립트를 이용해 영역이 다시 보이도록 만들었다.

 

다음으로 JavaScript 코드다. 여기서 두 가지 방식 즉, AJAX 와 Fetch를 이용했다. 기능적인 부분은 동일하지만 Fetch를 이용한 방법이 훨씬 간단하게 코드를 짤 수 있다. 둘 다 같은 기능을 구현한 거니 선택해서 사용하면 된다.

 

 

1) AJAX - XHR 방식

let fact = document.querySelector('#fact');
let factText = document.querySelector('#factText');

let numberInput = document.querySelector('#numberInput')
numberInput.addEventListener('input', getFactAjax);


function getFactAjax() {
  let number = numberInput.value; // input 입력 값
  let xhr = new XMLHttpRequest(); // XHR 생성자 생성

  xhr.open("GET", "http://numbersapi.com/" + number); // GET방식, API 요청
  xhr.onload = function () {// 요청이 성공적으로 완료되면
    if (this.status == 200 && number != "") { // 요청상태 확인 및 입력한 값이 있다면
      fact.style.display = 'block';
      factText.innerText = xhr.responseText;
    }
  };
  xhr.send();
}

number라는 변수는 input태그에서 입력한 값을 담고 있다. 이제 URL에 number를 붙여 GET방식으로 API 서버에 요청한다. 만약 성공적으로 응답을 받으면 div#fact 영역을 block으로 바꿔 보이도록 한다. 그리고 텍스트란에 받아온 응답 값을 표현해주면 성공적으로 앱이 완성된다.

 

 

2) Fetch 방식

let fact = document.querySelector('#fact');
let factText = document.querySelector('#factText');

let numberInput = document.querySelector('#numberInput')
numberInput.addEventListener('input', getFactAjax);

function getFactFetch() {
 let number = numberInput.value;

 fetch("http://numbersapi.com/" + number)
  .then((response) => response.text())
  .then((data) => {
    console.log(data);
    if (number != "") {
      fact.style.display = "block";
      factText.innerText = data;
    }
  })
  .catch((err) => console.log(err));
}

fetch 함수에 요청할 URL을 넣어준다. 성공적으로 응답을 받으면 response.text()를 이용해 promise 값을 리턴하도록 한다. 그 값이 data 인자로 들어가고, 입력값(number)이 있는지 확인 후, 응답 값을 보여주도록 한다. catch를 사용해 에러 처리를 했다.

 

 

여기서 사용한 Numbers API는 서버 요청, 응답을 공부하기에 가장 간단한 예제라고 생각한다. 2가지 방식으로 모두 공부해보면서 조금이나마 서버 요청과 응답을 이해할 수 있었다. 다음에 다른 자바스크립트 예제를 포스팅할 예정이다.

반응형

+ Recent posts