11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

 

<내 풀이>

- 1차 시도

n = int(input())
dots = []

for i in range(n):
    [x, y] = map(int, input().split())
    dots.append([x, y])

for j in range(0, n-1):
    curIdx = j
    for k in range(j+1, n):
        if(dots[curIdx][0] > dots[k][0]):
            curIdx = k
        if(dots[curIdx][1] > dots[k][1]):
            curIdx = k
    dots[j][0], dots[curIdx][0] = dots[curIdx][0], dots[j][0]
    dots[j][1], dots[curIdx][1] = dots[curIdx][1], dots[j][1]


for i in range(n):
    print(dots[i][0], dots[i][1])

: 시간 복잡도가 O(n^2)이라 안될 거 같았는데.. 역시나 시간 초과로 통과하지 못했다.

 

- 2차 시도

n = int(input())
dots = []

for i in range(n):
    dots.append(list(map(int, input().split())))

dots = sorted(dots, key=lambda x: (x[0], x[1]))

for i in dots:
    print(*i)

: 구글링을 통해 다른 사람들이 한 풀이를 참고했다. 일단 모르는 개념들이 많아서 이해하는데 어려움이 있었는데, 개념을 알고 나니 정말 간단하게 구현을 할 수 있다는 것을 알았다.

 

1) sorted(iterable, *, key=None, reverse=False)

 

: 첫 번째 인자로 정렬하고자 하는 반복 가능한 자료형을 넣는다. key인자의 값으로 함수를 넣어주면 함수의 반환 값을 기준으로 정렬을 해준다. 마지막 인자를 True로 하면 내림차순으로 정렬을 하게 된다.

 

2) lambda 함수

 

: 익명 함수를 만들 때 사용하며, 재사용이 되지 않는 간단하게 사용하는 함수이다. 함수명을 쓰지 않고 'lambda 인자 : 표현식' 형태로 사용하고 리턴 값을 보낸다.

 

3) Packing, Unpacking Operator *

 

반응형

 알고리즘, 자료구조 - 선택 정렬 

 

 

선택 정렬이란?

 

리스트 안의 원소들 중 최솟값을 찾아 리스트의 앞쪽으로 보내고, 그 뒤에 남은 원소들에 대해서 반복적으로 최솟값을 찾아 정렬하는 알고리즘이다. 간단한 알고리즘이지만 성능면에서는 느리기 때문에 좋지 않은 방식이다.

 

- 선택 정렬 알고리즘의 구체적인 개념

1. 첫 번째 원소를 선택, 그 뒤의 원소들과 차례대로 비교해 최솟값을 찾는다.

2. 찾은 최솟값을 첫 번째로 옮긴다.

3. 두 번째 원소를 선택, 3번째 원소부터 끝까지 비교해 최솟값을 찾는다.

4. 위의 과정들을 계속 반복한다.

 

위의 알고리즘 방식을 보면 코드상에서 2개의 반복문이 필요하고 이는 시간 복잡도 면에서 O(n^2)의 시간이 걸린다.

 

- 시간 복잡도

0번 요소: (n-1) 번 비교

1번 요소: (n-2) 번 비교

 ...

n-2번 요소: 1번 비교

n-1번 요소: 0번 비교

 

전체 비교 횟수는 0+1+2+3+...+n-2+n-1 = (n-1)(n-1+1) / 2 가 된다. n의 수가 커지면 결국 n^2이 큰 영향을 가지고 나머지는 무시할 수 있다. 따라서 시간 복잡도는 O(n^2)가 된다. 

 

<출처: 위키피디아>

 

예제

def select_sort(li):
    n = len(li)

    for i in range(0, n-1): #0번째~n-2번(뒤에서 2번째)
        min_idk = i
        for j in range(i+1, n): #비교하려는 값 뒤부터 끝까지 비교
            if(li[j] < li[min_idk]): # 비교하려는 값보다 뒤에 값이 작다면
                min_idk = j 		 
        li[i], li[min_idk] = li[min_idk], li[i] # 최솟값 위치 변경 

    return li


print(select_sort([2, 4, 5, 1, 3])) # [1, 2, 3, 4, 5]

 

 
 

 

반응형

 알고리즘, 자료구조 - 순차 탐색(선형 탐색) 

 

순차 탐색이란?

 

리스트 또는 배열 안에 있는 첫 번째 자료부터 하나씩 비교하면서 원하는 데이터를 찾아가는 알고리즘이다. 데이터를 따로 조작할 필요가 없어 단순하지만 비효율적이라는 단점을 지니고 있다. 추가로 순차 탐색은 단방향으로 탐색을 수행하기 때문에 선형 탐색(Linear Search)라고도 부른다.

순차 탐색은 최악의 경우에 최대 n번의 비교를 필요로 하기에 시간 복잡도는 O(n)이 된다.

이는 데이터가 n개가 되면 그에 따른 연산 수도 n개를 따라가기 때문에 자료수가 많아질수록 연산의 속도가 느리다는 단점이 있다.

 

 

 

예제

 

# 리스트에서 특정 숫자의 위치 찾기

def search_num(a, x):
	n = len(a)
    for i in range(0, n): #리스트 a의 모든 값에 대해 반복
    	if x == a[i] : 	# 찾는 숫자와 값이 일치하면
        	return i	# 인덱스 값 반환
    
    return -1
    
a = [17, 92, 18, 33, 58]
print(search_num(a, 18)) # 2 출력
print(search_num(a, 900)) # -1 출력(해당 값이 없기에)

 

# 학생 번호를 입력시 해당하는 학생의 이름을 반환
def find_student(number, stuNo, stuName):
    num = len(stuNo)
    for i in range(0, num):
        if(stuNo[i] == number):
            return stuName[i]

    return "해당 학생은 없습니다."


stu_no = [39, 14, 67, 103]
stu_name = ["Justin", "John", "Mike", "Summer"]

print(find_student(39, stu_no, stu_name)) #출력 - "Justin"
 

 

반응형

[AJAX] - Asynchronous JavaScript and XML

웹에 데이터를 갱신할 때, 브라우저 새로고침 없이 서버로부터 데이터를 받는 것이 좋겠다는 생각에서 시작됐으며, 더 좋은 UX를 제공할 수 있는 기술이다. 간단하게 AJAX는 서버와 통신하기 위해 XMLHttpRequest 객체를 사용하는 것을 말한다. JSON, XML, HTML 그리고 일반 텍스트 형식 등을 포함한 다양한 포맷을 주고받을 수 있습니다. 요즘 가장 많이 사용되는 데이터 포맷 형식은 JSON이다.

 

[특징]

1. 페이지 새로고침 없이 서버에 요청할 수 있다.

2. 서버로부터 데이터를 받고 작업을 수행한다.

 

[사용법]

1. XMLHttpRequest 객체를 이용한 방법

2. Fetch API를 이용한 방법 - XHR보다 간단하게 코드를 짜 서버와 통신을 쉽게 할 수 있다. 하지만 익스플로러에서는 적용이 되지 않는다고 하니, 참고해서 사용해야 한다.

 

 

[예제 - XHR(1)]

function ajax(data) {
 var xhr = new XMLHttpRequest();
 xhr.addEventListener("load", function() {
   console.log(this.responseText);
 });    
 xhr.open("GET", "http://www.example.org/getData?data=data");//parameter를 붙여서 보낼수있음. 
 xhr.send();
}

 

XMLHttpRequest객체를 생성해서, open메서드로 요청을 준비하고, send메서드로 서버로 보낸다.

요청처리가 완료되면(서버에서 응답이 오면) load이벤트가 발생하고, 콜백 함수가 실행된다.

콜백 함수가 실행될 때는 이미 ajax함수는 반환하고 콜 스택에서 사라진 상태다.

이는 setTimeout함수의 콜백함수의 실행과 유사하게 동작하는 '비동기'로직이다.

 

 

 

[XMLHttpRequest 객체의 메서드]

 

1. open 메서드

 

- 첫 번째 파라미터 

: HTTP 요구 방식(request method) ─ GET, POST, HEAD 중의 하나이거나 당신의 서버에서 지원하는 다른 방식이다.(반드시 대문자로)

 

- 두 번째 파라미터

: 요구하고자하는 URL 주소

 

- 세 번째 파라미터(옵션)

: 요구가 비동기식(Asynchronous)으로 수행될지를 결정한다. True(기본값)이면 자바스크립트 함수가 지속적으로 수행될 수 있어 서버로부터 응답을 받기 전에도 유저와 페이지의 상호작용이 계속 진행된다. 이것이 AJAX 의 첫 번째 A (Asynchronous : 비동기성)이다.

 

 

2. send 메서드

 

: GET방식으로 요청을 하는 경우에는 파라미터가 없다.

 

: send() 메소드의 파라미터는 POST 방식으로 요구한 경우 서버로 보내고 싶은 어떠한 데이터라도 가능하다. 데이터는 서버에서 쉽게 parse 할 수 있는 형식(format)이어야 한다.  JSON, XML, SOAP 등과 같은 다른 형식(format)도 가능하다.

예시) "name=value&anothername="+encodeURIComponent(myVar)+"&so=on" 

 

 

 

[Response 속성들]

1. readyState

 

  • 0 (uninitialized) - (request가 초기화되지 않음)

  • 1 (loading) - (서버와의 연결이 성사됨)

  • 2 (loaded) - (서버가 request를 받음)

  • 3 (interactive) - (request(요청)을 처리하는 중)

  • 4 (complete) - (request에 대한 처리가 끝났으며 응답할 준비가 완료됨)

2. status

 

  • 200: "OK"

  • 403: "Forbidden"

  • 404: "Page not found"

3. statusText

: "OK" or "Not Found" 반환

 

 

 

 

[예제 - XHR(2)]

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

        let xhr = new XMLHttpRequest();
        xhr.open("GET", "http://numbersapi.com/" + number);// url에 값을 추가

        xhr.onload = function () {
          if (this.status == 200 && number != "") {
            fact.style.display = "block";
            factText.innerText = this.responseText;
          }
        };

        xhr.send();
        }

 

[예제 - Fetch]

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

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

 

반응형

css postioning 

 

화면 상 어디에 위치시킬 것인가 지정하는 속성
html화면 기준 x, y좌표를 지정해 위치를 조정한다.

 

1. static

: position 속성의 기본값으로 다른 요소와의 관계를 가지며 자동으로 배치되어 위치 조정 불가능하다. 따라서 top, left, right, bottom 설정을 할 수 없다. 기본적으로 위에서 아래로, 왼쪽에서 오른쪽으로 아이템들이 쌓인다.

 

2. relative

: 다른 요소와의 관계를 가지며 자동으로 자신이 원래 있던 위치(즉, static일 때)를 기준으로 좌표를 지정한다.
주로 absolute속성과 같이 쓰일 때, 부모 컨테이너에 relative를 준다.

 

3. absolute

: 절대위치를 기점으로 좌표를 설정하고, static 속성을 가지고 있지 않은 부모를 기준으로 움직입니다. 만약 부모 중에 포지션이 relative, absolute, fixed인 태그가 없다면 가장 위의 태그(body)가 기준이 됩니다.

 

4. fixed

: window 즉 페이지를 기준으로 위치 설정(다른 position 값을 다 무시) 되며 스크롤을 내려도 항상 화면상의 그 위치에 있다. 화면의 절대 위치를 설정으로 위치가 고정되어진다. 그래서 보통 퀵메뉴, 메뉴바에 사용을 많이 한다.

 

5. sticky
: 원래 자리에 있으면서 대신 스크롤링 될 때, 없어지지 않고 원래 자리에 계속 위치함

 

 

예시

 

 

<body>
  <div class="box1">static</div>
  <div class="box2">relative</div>
  <div class="box3">absolute</div>
  <div class="box4">fixed</div>
</body>
body{
  border:3px solid green;
}

.box1{
  width:70px;
  height:70px;
  background-color: pink;
  position:static;
}
.box2{
  width:70px;
  height:70px;
  background-color: purple;
  position: relative;
  left:60px;
  bottom:20px;
}
.box3{
  width:70px;
  height:70px;
  background-color: orange;
  position: absolute;
  top: 30px;
  left:30px;
}
.box4{
  width:70px;
  height:70px;
  background-color: red;
  position: fixed;
  left:30px;
}
반응형

JavaScript Event Listener 

 

Event

 

이벤트(event)란 웹 브라우저가 알려주는 HTML 요소에 대한 사건의 발생을 의미한다. 웹 페이지에 사용된 자바스크립트는 이렇게 발생한 이벤트에 반응하여 특정 동작을 수행할 수 있다. 따라서 클라이언트 측 자바스크립트를 비동기식 이벤트 중심(event-driven)의 프로그래밍 모델이라고 한다. 브라우저에서 많은 이벤트들이 발생하는데, 브라우저 화면의 크기를 마우스로 조절할 때도, 스크롤을 할 때도, 마우스로 이동하거나 무언가를 선택할 때도 이벤트가 발생한다. 따라서 개발자는 HTML엘리먼트 별로 어떤 이벤트(주로 키보드나 마우스 관련)가 발생했을 때 특정 행위를(어떤 일) 하고 싶다면, 대상 엘리먼트를 찾고 어떤 일을 등록하면 된다.

 

 

 

이벤트 등록

 

 

이벤트 리스너(event listener)

 

사용법

 

target.addEventListener(type, listener[, options])

: type은 이벤트 리스너를 등록할 이벤트 타입을 문자열로 전달한다. listener로 해당 이벤트 타입을 처리할 함수를 설정해준다. 마지막으로, options으로 이벤트를 전파할 방식을 설정해주는 것인데, 버블링 또는 캡처링 방식이 있지만 보통 default값(false)을 사용하기에 사용을 잘하지 않는다.

 

 

이벤트 리스너란 이벤트가 발생했을 때 그 처리를 담당하는 함수를 가리키며, 이벤트 핸들러(event handler)라고도 한다. 지정된 타입의 이벤트가 특정 요소에서 발생하면, 웹 브라우저는 그 요소에 등록된 이벤트 리스너를 실행시킨다.

 

// HTML
<table id="outside">
    <tr><td id="t1">one</td></tr>
    <tr><td id="t2">two</td></tr>
</table>
//JavaScript
// 이벤트 리스너(함수)
function modify(new_text) {
  var t2 = document.getElementById("t2");
  t2.firstChild.nodeValue = new_text;    
}
 
// 이벤트 리스너 등록
var el = document.getElementById("outside");
el.addEventListener("click", function(){modify("안녕")}, false);
// 출력
one
two // one 클릭 시, "안녕"으로 바뀜

 

 

 

 

이벤트 객체

 

브라우저는 이벤트 리스너를 호출할 때, 사용자로부터 어떤 이벤트가 발생했는지에 대한 정보를 담은 이벤트 객체를 생성해서 리스너 함수에 전달한다. 이벤트 객체(event object)란 특정 타입의 이벤트와 관련이 있는 객체다. 모든 이벤트 객체는 이벤트의 타입을 나타내는 type 프로퍼티와 이벤트의 대상을 나타내는 target 프로퍼티를 가진다. 이러한 이벤트 객체는 이벤트 리스너가 호출될 때 인수로 전달된다.

 

var el = document.getElementById("outside");
el.addEventListener("click", function(evt){
 console.log(evt.target);
 console.log(evt.target.nodeName);
}, false);
// 출력

// one 클릭 시
<td id="t1">one</td>
TD

// two 클릭 시
<td id="t2">two</td>
TD

 

event.target은 이벤트가 발생한 element를 가리킨다.

element도 객체이므로 안에 nodeName이나 classname과 같이 element가 가진 속성을 사용할 수 있다.

반응형

 JSON.parse, JSON.stringify 

 

JSON

 

JSON은 객체, 배열, 숫자 ,문자열, boolean, null을 '직렬화'하기 위한 구문으로, JavaScript 구문에 기반을 두고 있지만 분명한 차이가 있다. 즉 JavaScript는 JSON이 아니다.

 

1. 객체와 배열
속성의 이름은 반드시 '큰따옴표'로 표시한 문자열이어야 한다. 


2.숫자
선행 0은 허용하지 않는다. 소숫점 뒤에는 적어도 한 자릿수가 있어야한다. Nan과 infinity는 지원하지 않는다.

 

3. JSON.parse()

 

문자열을 JSON으로서 구문 분석하고, 선택적으로 분석 결과의 값과 속성을 변환해 반환한다.

 

사용법

JSON.parse(text[, reviver])

 

매개변수

text : JSON으로 변환할 문자열

reviver : 함수라면, 변환 결과를 반환하기 전에 이 인수에 전달해 변형함.

 

반환값

주어진 JSON 문자열에 대응하는 Object(객체)

 

예외(오류)

변환할 문자열이 유효한 JSON이 아닐 경우 SyntaxError

 

const json = '{"result" : true, "count" : 42}';
const obj = JSON.parse(json);

console.log(obj.count); // output : 42
console.log(obj.result); // output : true
console.log(obj); //Object { result: true, count: 42 }
JSON.parse('{}');              // {}
JSON.parse('true');            // true
JSON.parse('"bamm"');           // "bamm"
JSON.parse('[1, 3, "false"]'); // [1, 3, "false"]
JSON.parse('null');            // null

 

4. JSON.stringify()

 

주어진 값(JavaScript 값이나 객체)에 해당하는 JSON문자열을 반환한다. 선택 사항으로 특정 속성만 포함하거나 사용자 정의방식으로 속성을 대체한다.

 

console.log(JSON.stringify({ x: 5, y: 6 }));
// expected output: "{"x":5,"y":6}"

console.log(JSON.stringify([new Number(3), new String('false'), new Boolean(false)]));
// expected output: "[3,"false",false]"

console.log(JSON.stringify({ x: [10, undefined, function(){}, Symbol('')] }));
// expected output: "{"x":[10,null,null,null]}"

console.log(JSON.stringify(new Date(2006, 0, 2, 15, 4, 5)));
// expected output: ""2006-01-02T15:04:05.000Z""

 

사용법

JSON.stringify(value[, replacer[, space]])

 

매개변수

value : JSON 문자열로 변환할 값

replacer : 문자열화 동작 방식을 변경하는 함수, 혹은 JSON 문자열에 포함될 값 객체의 속성들을 선택하기 위한 화이트리스트(whitelist)로 쓰이는 String  Number 객체들의 배열. 이 값이 null 이거나 제공되지 않으면, 객체의 모든 속성들이 JSON 문자열 결과에 포함된다.

 

반응형

 JavaScript 함수 - 선언, 호이스팅, 표현식, arguments, call stack, arrow function

1. 함수의 선언

 

함수는 여러 개의 인자를 받아서, 그 결과를 출력한다. 자바스크립트는 파라미터의 개수와 인자의 개수가 일치하지 않아도 오류가 나지 않는다. 만약 , 파라미터 1개가 정의된 함수를 부를 때, 인자의 개수를 0개만 넣어 실행하면, 이미 정의된 파라미터(매개변수)는 undefined 값을 갖게 된다. 이는 변수는 초기화됐지만, 값이 할당되지 않았기 때문이다.

 

// 함수선언문
function printName(firstname) {
    var myname = "jisu";
    return myname + " " +  firstname;
}

// 결과
jisu undefined

 

 

2. 함수 표현식

 

함수는 다음과 같이도 표현할 수도 있다.

 

// 함수표현식
function test() { 
    console.log(printName()); 
    var printName = function() {
        return 'anonymouse';
    }
}
test(); // 타입에러가 발생한다.

 

함수선언문과 달리 선언과 호출 순서에 따라서 정상적으로 실행되지 않을 수 있다. 표현식보단 함수 선언문을 더 자주 사용하지만, 어떤 코딩 컨벤션에서는 표현식을 권장하기도 한다.

 

 

 

3. 표현식과 호이스팅

 

위에 표현식 예제에서 printName이 "printName이 is not defined"이라고 오류가 나오지 않고, function이 아니라고 나온 이유는 printName이 실행되는 순간 'undefined'으로 지정됐기 때문이다.

자바스크립트 함수는 실행되기 전에 함수 안에 필요한 변수값들을 미리 다 모아서 선언한다.  함수 안에 있는 변수들을 모두 끌어올려서 선언한다고 해서, 이를 hoisting이라고 한다.
(실제로 코드가 끌어올려지는 게 아니라, 자바스크립트 파서 내부적으로 그렇게 끌어올려서 처리한다는 것이다)
따라서 다음 코드 역시 함수를 값으로 가지지만 어쨌든 printName도 변수이므로 끌어올려지고, 값이 할당되기 전에 실행됐으므로 undefined가 할당된 상태이다.

printName(); //아직, printName이 undefined으로 할당된 상태다.  
var printName = function(){}

 

 

 

4. 반환값과 undefined

 

다음 함수의 반환값은 undefined이다.

 

function printName(firstname) {
    var myname = "jisu";
    var result = myname + " " +  firstname;
}

 

자바스크립트 함수는 반드시 return 값이 존재하며, 없을 때는 기본 반환값인 'undefined'가 반환된다.
자바스크립트에서는 다른 언어에서의 void타입이 없다.

 

 

5. arguments객체

 

함수가 실행되면 그 안에는 arguments라는 특별한 지역변수가 자동으로 생성된다.
arguments의 타입은 객체이다. 자바스크립트 함수는 선언한 파라미터보다 더 많은 인자를 보낼 수도 있다.
이때 넘어온 인자를 arguments로 배열의 형태로 하나씩 접근할 수 있다. arguments는 배열이 아니다.
따라서 배열의 메서드를 사용할 수가 없다. 

 

function a() {
 console.log(arguments);
}
a(1,2,3);
// 결과
[Arguments] { '0': 1, '1': 2, '2': 3 }

 

자바스크립트의 가변 인자를 받아서 처리하는 함수를 만들 때 등에서 arguments속성을 유용하게 사용할 수가 있다. 하지만 arguments의 무분별한 사용은 하지 않는 게 좋다.

 

 

6. Arrow function

 

ES2015에는 arrow function이 추가됐다. 하지만 점점 많이 사용되고 있는 syntax이므로 같이 알아두어도 좋을 것 같다.

 

function getName(name) { 
   return "Kim " + name ; 
} 

//위 함수는 아래 arrow함수와 같다. 
var getName = (name) => "Kim " + name;

 

 

7. 함수의 연속적 호출(call stack)

 

여러 함수들(functions)을 호출하는 스크립트에서 해당 위치를 추적하는 인터프리터 (웹 브라우저의 자바스크립트 인터프리터 같은)를 위한 메커니즘이다. 현재 어떤 함수가 동작하고 있는지, 그 함수 내에서 어떤 함수가 동작하는지, 다음에 어떤 함수가 호출되어야 하는지 등을 제어한다.

 

function printing() {
   // [1] Some codes here
   sayHi();
   // [2] Some codes here
}
function sayHi() {
   return "Hi!";
}

printing();

// [3] Some codes here

 

실행 순서

1) printing() 함수 호출

2) 스택 리스트에 printing() 추가

3) [1] 실행, sayHi() 함수 호출

4) 스택리스트에 sayHi() 추가

5) sayHi() 종료 후, 호출된 곳으로 돌아감

6) 스택 리스트에서 sayHi() 제거

7) printing()의 나머지 코드 실행[2]

8) printing() 종료 후, 호출된 곳으로 돌아감

9) 스택 리스트에서 printing() 제거

10) [3] 코드 실행

반응형

+ Recent posts