'단조롭고 즐거운 일상 > 먹먹글' 카테고리의 다른 글

더블포테이토피치세트 먹먹  (0) 2016.10.30
신촌 SICTAC 먹먹  (0) 2016.10.25
BBQ 자메이카 먹먹  (0) 2016.10.25
귤먹  (0) 2016.10.25
닭발 먹먹  (0) 2016.10.25


서론. 


우리 사이트 내 다음 5가지의 공유 기능이 붙어야 했다. 

  1. 카카오톡
  2. 카카오스토리
  3. 페이스북
  4. 트위터
  5. 네이버


모든 기능은 각 api의 개발 문서를 참고해서 스크립트만으로 쉽게 만들 수 있다.

쉽게 만들 수 있지만, (항상 그렇듯이) 내가 하려던 것이 되지 않아 애를 먹었다.


그거슨 바로 5. 네이버 공유하기 기능.


네이버 공유하기 기능에 대한 개발 문서는 다음에서 찾아볼 수 있다. 

https://developers.naver.com/docs/share/navershare   



첫번째 당황. 하란대로 했는데요..?


넘나 간단하고 명료한 예시에서는 다음과 같이 하면 된다고 하는데... 8ㅅ8 거짓부렁이다.


인코딩 : UTF-8
요청방식 : GET방식
http://share.naver.com/web/shareView.nhn?url=인코딩한URL값&title=인코딩한title값


#파라미터설명
1url문자열인코딩한 공유할 웹 URL
2title문자열 (optional)인코딩한 제목 문자열



음...  title이 optional이라고 되어있는데, title을 넣어주지 않으면

"url 또는 title 정보가 없습니다." 라는 alert이 뜨면서 안된다. 


url과 title모두 인코딩해서 넘겨주어야 에러가 나지 않는다 :) 


스크립트로는 다음과 같이 작성해주면 된다.


<button type='button' id='naver_share'>네이버 공유 버튼</button>


<script>

$("#naver_share").click(function(e) {     

var share_url = '공유할 url주소';

var title = '포스팅/글의 제목';

  var url = 'http://share.naver.com/web/shareView.nhn?url='+encodeURIComponent(share_url)+'&title='+encodeURIComponent(title);

  window.open(url);

   });

</script>



두번째 애먹음. 썸네일 왜 그래요.. url.. 왜 나한테 그래요...


우리사이트 내에서 공유할 주소에는 각 사용자의 추천코드가 함께 붙어있다. 즉, 공유된 블로그/카페의 포스팅을 타고 들어오면, 추천코드가 함께 붙어있어야 하는데....

네이버 공유하기 api로 포스팅 된 것에는 썸네일과 링크가 마음대로 붙어버렸다.


이를 테면, 내가 공유하려던 url이

http://prosaist0131.tistory.com/8 이라면,

링크가 자꾸 http://prosaist0131.tistory.com으로만 붙어버렸다. 썸네일도 마음대로 되지 않았다. 


애를 먹다가, 네이버 개발자 포럼을 확인하다 다음의 질문 글을 발견하였다.

http://forum.developers.naver.com/t/topic/1133


글을 읽어보니, 네이버는 http://ogcrawler.blog.naver.com/crawler.json 를 통해서, 링크의 정보를 가지고 오는 것 같다는 거였다.

해당 crawler.json에 내가 공유하려던 url을 확인해보았다. 


썸네일과 링크가 내가 공유하려는 페이지의 메타 태그에 있는 것으로 연결이 되고 있었다. 

그래서 다음과 같이 간단히(?) 해결했다.


내가 공유하려고 했던 페이지 url을 메타태그로 가진 페이지를  만들어서 그 페이지를 공유하도록 했다. 

예를 들면 다음과 같다. 


<!DOCTYPE html>

<html>

<head>

<title>페이지 이름</title>

<!-- meta info -->

<meta name="keywords" content="키워드들">

<meta name="description" content="설명">

<meta property="og:title" content="페이지제목 "/>

<meta property="og:image" content="원래 공유하려고 했던 썸네일 이미지"/>

<meta property="og:url" content="원래 공유하려고 했던 페이지 URL"/>

<meta property="og:description" content="구체설명"/>


<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no" />

<meta http-equiv="X-UA-Compatible" content="IE=Edge"/>

<meta charset="utf-8">

(생략).




해결~ 끄읏...

트리에 대하여


/*

서론. 

그래프를 먼저 공부하고 트리를 정리했어야했는데 조금 아쉽다.

트리는 그래프의 한 종류이기 때문이다. 

트리로 검색했을 때 중복되어 나오는 결과들은 다음과 같다. 

  • 자료들 간에 계층관계를 가진 계층형 자료구조
  • 순환을 갖지 않는 연결그래프 
  • 비선형 자료구조
  • 나무를 뒤집어 놓은 모양새여서 트리라고 부른다
  • 이진 트리
  • 이진 탐색 트리
  • DFS순회/BFS순회
  • in-order, pre-order, post-order (전위, 중위, 후위) 순회
  • 레드-블랙 트리, AVL
  • 기타 그 밖의 용어들(레벨, 차수, 단말 노드, 부모, 형제, 자손 등...)
하나하나 찾다보면 아예 모르는 것들은 아닌데(들어본 것들인데), 도대체 트리를 왜 써먹어야 하는지 잘 모르고 있었던 것 같다.
특히, 자료 구조시간에 지겹게 나왔던 순회.
재귀로 간단히 구현할 수 있다는 것을 알고있으나, 왜 굳이 순회를 해야하는지 생각해 본 적 없어 정리해보고자 한다. 
아직 완벽히 정리(이해)는 되지 않아서 좀 부족한 것 같지만.... 
*/


1. 트리는 무엇이고 왜 써야하는가?

트리와 그래프는 비선형 데이터 구조이며, 트리는 계층형 데이터 구조이다. 

선형 데이터 구조로는 계층형 구조를 나타낼 수 없기 때문에, 트리라는 자료구조를 활용한다. 
선형 데이터 구조는 데이터를 구성하는 원소들이 순차적으로 나열된 데이터 구조이다. 리스트(선형, 연결) , 스택, 큐, 데크 같은 것들이다. 

계층으로 나타낼 수 있는 예로, 가족 관계도를 생각해보면.. 
가족 관계를 선형으로 나타내기는 굉장히 어렵다. 또한, 선형데이터로 나타낸 가족 관계도에서 내 조카를 찾아보라고 하면 굉장히 찾기 어려울 테다. 

트리는 주로 탐색을 하기 위해 사용된다. 폴더 구조, DBMS, 검색 엔진 등에서 활용이 된다. 


2. 트리의 용어에 대해서

용어는 생략하고 싶다. 정리하기 지겹지만.. 자주 헷갈리는 것만 적어보자면.. 
  • 차수(degree)
    • 차수란 노드에서 뻗은 가지의 수 중, 가장 많이 뻗은 가지의 수를 트리의 차수라고 말한다.  
  • 높이(height)
    • 루트 노드부터 시작해서 맨 끝에 있는 리프 노드까지의 깊이
  • 깊이
    • 루트 노드부터 해당 노드까지의 경로의 길이
  • 레벨
    • 각 노드의 층의 번호. 
그림이 없어 설명하기 힘들다. 그치만, 그림 그리기가 너무나도 귀찮아서 다음 용어들은 생략..! 
  • 루트노드
  • 부모노드 
  • 자식노드
  • 단말노드(리프노드)
  • 형제노드 

3. 이진트리

트리구조를 저장하는 방법은 여러가지가 있다. 
흔한 방법으로는 1. n링크 방법 2. 왼쪽 자식, 오른쪽 형제 노드(left-child, right-sibling) 방법 등이 있다.

1. n링크 방법은, 노드에 자식의 개수 만큼 n개의 링크를 두고, 링크는 트리가 저장된 곳을 링크하는 방법이다.
한번에 찾을 수 있기에 시간 복잡도가 O(1)인 장점이 있지만 데이터안에 빈공간이 많게 된다. 모든 데이터가 차수의 링크를 가져야하기 때문이다. 
또한, 노드의 수가 늘어나게 되면 적용하기 어렵다. 실제적으로는 노드의 개수가 정해질 때보다 가변적일 때가 많은데, 그렇게 되면 동적배열을 사용해야하고.. 그러면 구현하기가 어려워져서 
잘 사용하지 않는다. 그래서



2. 왼쪽자식, 오른쪽 형제 노드 방법이 있다. 이건 포인터로 왼쪽에는 자식을, 오른쪽에는 형제를 표시한다.
왼쪽자식, 오른쪽 형제 노드를 이용하면 이진 트리로 표현할 수 있는 장점이 있다.(조금만 기울여 보면 이진트리가 된다.)
시간 복잡도는 n링크 방법보다 더 걸리지만, 구현이 매우 쉽다. 단점은 n링크처럼 원하는 위치의 노드에 한번에 방문하기 어렵다.



 

그럼 이진트리는 왜 필요한걸까? 이진 트리가 중요한 이유는 구현이 매우 간단하기 때문이라고한다. N링크법은 활용하기도 힘들고, 여러 변형 트리 기법을 적용하기 어려운데, 이진 트리는 자식의 갯수가 무조건 두개로 고정되어 있기 때문에 활용이 편리하다고 한다. 

이진트리의 모양새에 따라 이진트리는 또 여러 종류로 나뉘는데 스큐이진트리(편향이진트리), 포화 이진 트리, 완전 이진트리 등이 있다.
그림을 보면 간단한데, 스큐 이진트리는 한쪽으로 편향된 모양새 포화이진트리는 꽉 찬거고 완전이트리는 위에서 부터 왼쪽에서부터 차례대로 차곡차곡 쌓여잇는 것 이다.

4. 그놈의 순회 왜해야하는 걸까?

트리를 정리해놓은 자료를 살펴보면, 보통 이런 흐름이다.
트리는 무엇인지? 트리의 용어 정리, 이진트리, 이진트리의 순회.

모든 노드를 거쳐가는 것을 순회라고 한다. 
순회가 필요한 경우는 주로 연결리스트로 트리가 구현되어있을 경우이다.
트리는 선형구조가 아닌 비선형 구조이기 떄문에 모든 노드들을 거쳐가기 위한 방법이 필요한 것이다. 
예를 들자면, 데이터를 삭제해야하는 경우 서브트리를 삭제하기 위해서는 모든 노드를 거쳐야지만 삭제할 수 있기때문에 순회가 필요하다.   

일단, 순회방법에는 깊이우선탐색(DFS) 와 너비우선탐색(BFS)가 있고,
자료구조 시간에 지겹게 본 pre-order, in-order, post-order 순회는 깊이우선탐색기법(DFS)이다. 

왜 순서를 나누는지 잘 모르겠어서 블로그를 찾다가 다음 포스팅을 발견했다. http://www.geeksforgeeks.org/618/

- In case of binary search trees (BST), Inorder traversal gives nodes in non-decreasing order. To get nodes of BST in non-increasing order, a variation of Inorder traversal where Inorder itraversal s reversed, can be used.


- Preorder traversal is used to create a copy of the tree. Preorder traversal is also used to get prefix expression on of an expression tree. Please see http://en.wikipedia.org/wiki/Polish_notation to know why prefix expressions are useful.


Postorder traversal is used to delete the tree. Please see the question for deletion of tree for details. Postorder traversal is also useful to get the postfix expression of an expression tree. Please see http://en.wikipedia.org/wiki/Reverse_Polish_notation to for the usage of postfix expression.

요약하자면

- inorder(중위순회)는 이진탐색트리에서 오름차순으로 노드를 얻는데 사용할 수 있다. 
- preorder(전위순회)는 트리의 복사본을 생성하기 위해 사용하거나, 수식트리에서 prefix 수식을 얻는데 사용할 수 도 있다. 
- postorder(후위순회)는 트리의 삭제에 이용되며 수식트리에서 postfix 수식을 얻는데 사용된다. 

위의 세가지는 재귀를 통해 간단하게 구현할 수 있다.



다음과 같은 이진트리가 있다고 가정하면

inorder같은 경우 노드의 방문 순서는 LVR로 6-2-8-1-5
preorder의 노드의 방문 순서는 VLR로 1-2-6-8-5
postorder의 노드의 방문 순서는 LRV로 6-8-2-5-1 이다.

너비탐색(BFS)의 경우에는 큐를 이용하여 구현할 수 있다. 너비 탐색을 이용하면 노드의 방문순서는 1-2-5-6-8이 된다. 
각 레벨의 노드를 큐에 추가하고 각 자식의 노드들을 모두 큐에 넣으면서 하나씩 반환하면 된다. 

5. 이진 탐색 트리

이진 탐색트리는 이진 탐색이 적용된 이진트리이다. 이진탐색트리의 특징은 왼쪽 자식 노드는 부모 노드보다 작고, 오른쪽 자식 노드는 부모 노드보다 커야한다는 것이다. 다음은 이진 탐색 트리의 예이다.

이진 탐색 트리의 예


이진탐색트리에서는 탐색, 삽입, 삭제 세가지 연산을 할 수 있다. 

삭제의 경우만 탐색이나 삽입보다 복잡한 편이다.

삭제하려는 노드가 단말 노드인 경우는 링크를 null로 만들어 주면 되고

삭제하려는 노드가 하나의 자식노드를 가지고 있을때에는 자식 노드가 그 자리를 대체한다.

삭제하려는 노드가 두개의 자식 노드를 가지고 있을 떄에는 왼쪽 서브트리에서 가장 큰 값으로 대체하거나, 

오른쪽 서브트리에서 가장 작은 값의 노드로 대체한다. 


6. 트리의 균형잡기

왜 레드블랙 트리, B-tree, AVL 트리 같은 것들이 필요할까?
이진탐색트리에 값을 삽입하다보면 스큐이진트리가 될때가 있다... 
다음 두 그림은 모두 이진탐색트리의 규칙을 어긋나지 않는, 이진 탐색 트리이다. 


그러나, 1이라는 노드를 탐색한다고 가정하면, 두 트리의 탐색 속도는 오른쪽이 빠르다.

트리의 균형이 맞지 않으면, 왼쪽 처럼 그냥 일반 연결리스트에서 찾는 것과 다름없게 된다. 


레드블랙트리, 비트리, AVL트리는 이러한 문제를 해결하기 위한 방법으로 고안된 발전된 고급 이진트리들이라고 생각하고 있다.


비트리(B-tree)는 자식을 두개만 가질 수 있는 이진 트리를 확장하여 더 많은 자식을 가질 수 있으며 자동으로 균형을 맞춘다. 

레드블랙트리는 이진 트리에 색상이라는 속성을 노드에 추가하여 자동으로 균형을 잡도록 만드는 트리이다.

AVL트리도 LR회전 LL회전 RR회전 RL회전 등을 통해서 자동으로 트리의 균형을 맞추기 위해 만들어진 알고리즘이다.



'개발개발 > 자료구조와 알고리즘' 카테고리의 다른 글

그래프  (0) 2016.10.25
Array 와 ArrayList 와 LinkedList 의 차이  (0) 2016.07.10

/*

서론. 


자료구조를 공부하면서 Array를 배웠고, LinkedList를 구현하는 법도 배웠다. 

JAVA 수업을 들으면서 ArrayList를 사용했다.  


얼핏 기억하고 있던 각 자료구조의 특징은 다음과 같다.

  • Arrayindex로 빠르게 값을 찾을 수 있다.
  • LinkedList는 데이터를 삭제하고 삽입하는데 빠르다
  • ArrayList는 데이터를 찾는데 빠르지만 데이터의 삽입과 삭제가 느리다.

창피하지만 그 차이가 뭔지 와닿지가 않았고, 이해가지 않았다. 

DP로 자료구조 공부를하면서 이제야 조금 이해했다. 물론, 아직 다 이해하지 못했을 것이다.

이걸 그동안 몰랐다니 넘나 부끄럽지만 나중에라도 다시 이 바보스러움을 느끼기 위해 조금이나마 이해한 바를 정리해본다.

*/



1. array는 뭘까?


array는 뭘까? array는 배열이지. 


일반적으로 array는 array의 크기와 데이터 타입을 함께 선언해야 한다. 

이를테면, 이런식으로


int arr[6]; 

String arr[12];


array는 왜 선언하기 전에 자료형과 사이즈를 함께 적어줘야할까? 뭐 배열이 커질수도 있구 어떻게 될지 알지도 못하는 일인데 말이다.


int arr[6]을 예로 들면, 괄호 안 6은 배열의 길이를 뜻한다. int형 데이터가 들어갈 공간 6개가 메모리 공간에 할당된 것이다.

즉, 특정 자료형의 변수가 들어갈 공간을 몇개나 할당할지를 정한다. 


array는 데이터를 줄줄이 저장한다. 그래서 각 데이터가 줄줄이 저장될 것이기 때문에 자료형을 미리 적어주어야 한다. 


array는 데이터를 찾는게 빠르다. 

왜? index가 있으니까. 이 array는 데이터를 줄줄줄 저장하다 보니까. 위치를 바로 알 수가 있다. 

내가 arr[4]를 찾는다고 하면 arr라는 것의 주소값에서 바로 +4만해서 찾으면 되니까. 검색이 빠르다. 


array[4]에다가 t새로운 값을 넣으면 어떻게 될까? 덮어씌워진다. 

array[4]를 삭제하면 어떻게 될까? 그냥 텅 비어있을 뿐이다. 


그래서 arrayList가 나오게 된다. 


2. List는 뭘까?


나는 넘나 헷갈렸었다. 무엇이? array나 list나 그게 뭔 차이가 있는 건지.

array와 list의 가장 큰 차이점은. 


array크기를 정해주어야 한다는 것. index가 중요하다는 것. 

list크기가 정해지지 않아도 된다는 것. 순서가 중요하다는 것이다. 


이 차이를 알기 위해 arrayList를 보자.

array에서는 arr[4]에 새로운 값을 대입하면 덮어씌워진다.

array에서는 arr[4]를 삭제하면 텅비어있다. 


arrayList에서 만약 arrList.add()하면 어떻게 될까? 4번째 에다가 더한다면? 그러면 얘는 4번쨰에 들어간다. 

arrayList.remove()하면 어떻게 될까? 다 줄줄이 당겨진다. 


그래서 arrayList에서 값을 맨앞에 넣거나 맨뒤에 넣으면 상관이 없는데 중간에 값을 더하거나, 빼면 오래걸리는 거다. 

대신 array의 성질, 즉 index를 그대로 가지고 있기 때문에 자료를 검색하는데는 빠르다. 

List는 크기를 미리 정해줄 필요가 없다. 쭉쭉 이어진다. 



LinkedList는 그럼 어떨까?

단일 연결리스트, 다중 연결리스트 등. 여러 Linked list가 존재한다. 

단일이든, 다중이든 링크드 리스트는 한 노드에 연결될 노드의 포인터 위치를 가르킨다. 

다중은 앞뒤 모두 다 가르키는 거고, 단일은 뒤에것만 가르키는 거구 


이렇게 되니까, 데이터를 중간에 넣고 뺀다고 해도 이전에 가르치는 값, 다음 값이 가르켰던 값만 연결시켜주면 되니 빠르다.


그렇지만 11번 째 값을 찾는다고 생각해보자. 

그러면 얘는 맨처음부터 굽이굽이 건너가야 한다. 그래서 값을 찾는데는 arrayList나 array보다는 좀 걸린다. 

'개발개발 > 자료구조와 알고리즘' 카테고리의 다른 글

그래프  (0) 2016.10.25
트리에 대하여  (0) 2016.10.16

1. 

'코멘토'에서 인턴으로 근무하게 되면서 처음으로 PHP를 접하게 되었다. 

첫 출근 날이 16.01.07 목요일인가 금요일인가 그랬으니 PHP란 언어를 사용하게 된지 어느새 6개월이 지나갔다. 


2. 

IT를 복수전공하고 컴퓨터를 전공했다기엔 너무, 너무나 부족한 기본기. 그리고 넘나 부족한 실전 경험. 

보안, 재사용성, 리팩토링, 코드의 간결함, 시간복잡도와 공간복잡도 따위 한번도 고민해보지 않았던 '야매' 대학원생이었던 나는 ASAP이 덕목인 스타트업에서 빠르게 개발하고 적용하는 상황에 이르자 매우 혼란스러웠다.  


3. 

그래도 여차저차 일해보니 지금이 되었다. 정말 여차저차. (DB를 날리기도하고.. 서버 마비도 시키고.. ) 여전히 개발에 대해서 1도 모르지만, 0.1 정도는 알게 되지 않았나 싶다. 원체 '빠르게'를 모르던 사람이 '빠르게' 일하려다 보니 많은 것을 배우고 있다. 난 좀 빠르게가 필요한 사람이기에. 

그렇지만 빠르게 하려다 보니, 모르고 지나가는 것들이 많은 것 같다. PHP의 심볼이 코끼리이며 그 이유는 'PHP'가 코끼리 같이 생겨서 그렇다는 귀여운 사실을 몰랐다. 안드로이드를 경험해봤음에도 불구하고 아직 모르는 것이 많다. SQL도 그렇다.


4.

이제 좀 '학습'이 필요한 시기인 것 같다. 개념을 아무리 외워봤자, 직접 경험해보지 않으면 알 수 없다.  

자료구조 수업을 들었고, 성적이 좋은 편이었음에도 불구하고 이제와 Array와 list의 차이를 이해하게 되었다.    

사용하는 언어와 자료구조, 알고리즘에 대한 학습이 필요하다. 


5. 

결론은, 이제부터 열심히 학습해보겠다는 거다. 

일하면서 알게된 것들과, 학습한 것들을 정리하고자한다. (아무래도 코멘토에서 사용하는 언어와 기술이 주가 될 것 같다.) 

재밌게 정리하고 공부하고 싶다. 

나와 같은 혼란을 겪고 있는 쌩초보 개발자들이 공감할 수 있고 도움을 얻어갈 수 있는 블로그, 스스로가 성장하고 있음을 느낄 수 있는 블로그가 되었음 좋겠다.  

'개발개발' 카테고리의 다른 글

DDD Start! 정말?  (0) 2018.11.20
과학과 예술에 대해서, 그리고 Bubblesortzines  (0) 2018.08.17
MR과 PR의 차이  (0) 2018.03.04
개발 공부하기 좋은 유용한 사이트 정리  (0) 2017.10.09

+ Recent posts