728x90
반응형

알고리즘 문제를 풀다보면 정렬을 해야하는 경우가 많이 발생합니다. 기본적으로 제공되는 Arrays.sort() 함수가 있지만 이것만으로 문제를 풀기에는 한계가 있습니다. 특히 다중차순을 요하는 문제는 직접 구현하는 것이 빠르고 이해가 쉽습니다.

 

기본적인 정렬 코드

아래는 오름차순, 내림차순, 다중차순의 기본 정렬 구현 코드입니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;
import java.util.Comparator;


class Node implements Comparable<Node>{
	int a;
	int b;
	
	public Node(int a, int b){
		this.a = a;
		this.b = b;
	}

	@Override
	public int compareTo(Node tar) {
		
		// tar 기준으로 tar vs this 중 tar 우선순위가 더 높으면 1
		// tar 기준으로 우선순위가 동등하면 0
		// tar 기준으로 tar vs this 중 tar 우선순위가 더 낮으면 -1
		
		if(tar.a > this.a) return 1;
		if(tar.a < this.a) return -1;
		
		// 첫 수가 우선쉰위가 도등할때 아래 조건을 따른다.
		if (tar.b < this.b) return 1;
		if (tar.b > this.b) return -1;
		
		return 0;
	}
}

public class Sort_ex01 {

	// 정렬
	// 1. 오름차순 
	// 2. 내림차순 
	// 3. 다중차순

	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

	
    public static void main(String[] args) throws IOException {

        Integer[] arr = {5,4,5,4,4,5};
        
        //1. 오름차순
        Arrays.sort(arr);
        
        //2. 내림차순
        Arrays.sort(arr, Comparator.reverseOrder());
        
        //3. 다중차순
        Node[] arrNode = new Node[6];
        arrNode[0] = new Node(5,8);
        arrNode[1] = new Node(4,2);
        arrNode[2] = new Node(5,1);
        arrNode[3] = new Node(4,9);
        arrNode[4] = new Node(4,7);
        arrNode[5] = new Node(5,3);
        
        // 정렬조건
        // 1) 첫번째 수가 큰수 우선
        // 2) 두번째 수가 작은 수 우선        
        Arrays.sort(arrNode);
        
        int a=1;

		br.close();
		bw.close();

    }
}

오름차순, 내림차순은 Arrays.sort() 함수를 이용하여 구현이 간단합니다. 하지만 다중차순의 경우 정렬 조건이 1) 첫번째 수가 큰수, 2) 두번째 수가 작은 수 우선이라고 한다면 위 코드와 같이 class 를 만들어 Comparable 을 이용하여 구현하여 줍니다. 정렬 우선순위는 compareTo() 함수를 오버라이드 하여 구현하는데, tar 기준으로 tar vs this 중 tar 우선순위가 더 높으면 1,  tar 기준으로 우선순위가 동등하면 0,  tar 기준으로 tar vs this 중 tar 우선순위가 더 낮으면 -1 이 중요합니다. 

이러한 방법을 통하여 "숫자와 문자를 다음과 같은 우선순위 조건으로 맞추어 정렬 후 출력" 하는 문제도 해결이 가능합니다. (ex, 1)짝수 우선 2)숫자 오름차순 3)문자 오름차순)

 

정렬은 알고리즘에서 응용을 많이 하는 것으로 방법을 꼭 숙지하여야 합니다.

728x90
반응형
728x90
반응형

플러드 필 알고리즘은 다차원 배열의 어떤 카과 연결된 영역을 찾는 알고리즘 입니다. 그림 프로그램에서 연결된 비슷한 색을 가지는 영역에 "채우기" 도구에 사용되며, 바둑이나 지뢰 찾기 같은 게임에서 어떤 비어 있는 칸을 표시 할 지를 결정할 때에도 사용됩니다.

 

동작과정

  1. 시작하는 칸을 큐에 넣고 방문했다는 표시를 한다.
  2. 큐에 원소를 꺼내어 그 칸에 인접한 칸(ex. 상,하,좌,우)에 대하여 3과 같이 동작한다.
  3. 인접한 칸에 대하여 방문여부를 판단하여 처음 방문했다면 방문 표시를 남기고 큐에 넣는다.
  4. 큐의 모든 원소가 빌 때까지 2의 행동을 반복한다.

시간복잡도

모든 칸이 큐에 1번 들어가는 것이 보장되므로 칸이 N개일 때 시간복잡도는 O(N) 입니다.

참고사이트

https://choijiuen.tistory.com/99
 

플러드 필(Flood Fill) - BFS , DFS

다차원 배열에서 어떤 칸과 연결된 영역을 찾는 알고리즘 그림판에서 색 채우기 명령으로 동일한 색을 전부 바꿔버리는 것과 동일하다. 플러드 필 문제는 BFS/DFS 알고리즘으로 해결할 수 있다. BF

choijiuen.tistory.com

https://ko.wikipedia.org/wiki/%ED%94%8C%EB%9F%AC%EB%93%9C_%ED%95%84
 

플러드 필 - 위키백과, 우리 모두의 백과사전

4방향 재귀적 플러드 필 플러드 필(영어: flood fill) 혹은 시드 필(영어: seed fill)은 다차원 배열의 어떤 칸과 연결된 영역을 찾는 알고리즘이다. 이 알고리즘은 그림 프로그램에서 연결된 비슷한 색

ko.wikipedia.org

기본코드

2차원 배열 (4*4) 에서 2,1 에서 시작하여 모든 배열을 도는데 걸리는 cnt를 알아내는 예제입니다.

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.LinkedList;
import java.util.Queue;

class PNode {
    int y, x;
    PNode(int a, int b)
    {
        y = a;
        x = b;
    }
}

class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    static int [][]map = new int[4][4];
    static Queue<PNode> q = new LinkedList<PNode>();

    public static void main(String[] args) throws IOException {        

        map[2][1] = 1;
        q.add(new PNode(2, 1));

        int[][] direct = {{-1, 0}, {1, 0}, {0, 1}, {0, -1}};
        int cnt = 0;

        while(!q.isEmpty()) {
            PNode now = q.poll();

            //now에서 다음 퍼지는 길 모두 등록
            for (int t = 0; t<4; t++ ) {
                int ny = now.y + direct[t][0];
                int nx = now.x + direct[t][1];
                if (ny < 0 || nx < 0 || ny >= 4 || nx >= 4) continue;
                if (map[ny][nx] != 0) continue;

                map[ny][nx] = map[now.y][now.x]+ 1;
                if (map[ny][nx] > cnt) cnt = map[ny][nx];

                q.add(new PNode(ny, nx));
            }
        }

        bw.write(cnt + "\n");

        br.close();
        bw.close();
    }
}

실행하여 map 의 변화를 알아보면 처음 map은 (2,1) 에서 시작하기 때문에 아래와 같다.

[0, 0, 0, 0]
[0, 0, 0, 0]
[0, 1, 0, 0]
[0, 0, 0, 0]

전부 완료되었을때 map 은 아래와 같이 변경된다.

[4, 3, 4, 5]
[3, 2, 3, 4]
[2, 1, 2, 3]
[3, 2, 3, 4]

위와 같은 결과로 모든 배열이 채워지는데 마지막 숫자인 5가 결과로 나타난다.

728x90
반응형
728x90
반응형

컴포넌트

컴포넌트란 조합하여 화면을 구성할 수 있는 블록을 의미합니다. 화면을 빠르게 구조화하여 일괄적인 패턴으로 개발할 수 있습니다. 화면의 영역을 컴포넌트로 쪼개서 재활용할 수 있는 형태로 관리하면 나중에 코드를 다시 사용하기가 편리합니다. 참고로 컴포넌트 간의 관계는 자료구조의 트리(Tree) 모양과 유사합니다.

 

- 컴포넌트 등록하기

컴포넌트를 등록하는 방법은 전역과 지역 두 가지가 있습니다.

  • 지역(Local) 컴포넌트 : 특정 인스턴스에서만 유효한 범위를 가지고 있음, 특정 범위에서만 사용
  • 전역(Global) 컴포넌트 : 여러 인스턴스에서 공통으로 사용할 수 있음, 뷰로 접근 가능한 모든 범위에서 사용 가능

전역 컴포넌트 등록

뷰 라이브러리를 로딩하고 나면 접근 가능한 Vue 변수를 이용하여 등록합니다. Vue 생성자에 .component()를 호출하여 됩니다. 형식은 아래와 같습니다.

Vue.component('컴포넌트이름', {
    // 컴포넌트 내용
});

아래는 전역 컴포넌트를 1개 등록하고 화면에 그리는 예제입니다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Vue component registration</title>
  </head>
  <body>
    <div id="app">
      <button>컴포넌트 등록</button>
      <my-component></my-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      Vue.component('my-component',{
        template : '<div>전역 컴포넌트가 등록되었습니다.</div>'
      });

      new Vue({
        el:'#app'
      });
    </script>
  </body>
</html>

 

아래는 실행결과 화면 입니다.

인스턴스가 생성되고, 인스턴스 내용이 화면 요소로 변환될 때 컴포넌트 태그도 함께 변합니다. 아래는 처리과정 입니다.

뷰 라이브러리 파일 로딩 → 뷰 생성자로 컴포넌트 등록 Vue.component() → 인스턴스 객체 생성 → 특정 화면 요소에 인스턴스 부착 → 인스턴스 내용 변환 (<my-component> 가 <div>로 변환됨) → 변환된 화면 요소를 사용자가 최종 확인

 

지역 컴포넌트 등록

지역 컴포넌트는 전역 컴포넌트 등록과 다르게 인스턴스에 components 속성을 추가하고 등록할 컴포넌트 이름과 내용을 정의하면 됩니다.

new Vue({
    components: {
        '컴포넌트 이름': 컴포넌트 내용
    }
})

아래는 지역 컴포넌트 등록 예제입니다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Vue component registration</title>
  </head>
  <body>
    <div id="app">
      <button>컴포넌트 등록</button>
      <my-local-component></my-local-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      var cmp = {
        // 컴포넌트 내용
        template: '<div> 지역 컴포넌트가 등록되었습니다.</div>'
      };

      new Vue({
        el:'#app',
        components: {
          'my-local-component':cmp
        }
      });
    </script>
  </body>
</html>

 

아래는 실행 결과 입니다.

 

여기까지 지역 컴포넌트 등록과 전역 컴포넌트 등록에 대해 알아보았습니다. 그렇다면 이 둘의 차이점은 무엇일까요?

 

지역 컴포넌트와 전역 컴포넌트의 차이

차이점을 이해하기 위해서는 인스턴스의 유효 범위를 이해해야 합니다. 다시 이야기하면, 인스턴스의 유효 범위란 HTML의 특정 범위 안에서만 인스턴스의 내용이 유효한 것 입니다. 아래 코드를 보도록 하겠습니다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Vue component registration</title>
  </head>
  <body>
    <div id="app">
      <h3>app 인스턴스 영역</h3>
      <my-component></my-component>
      <my-local-component></my-local-component>
    </div>
    <hr/>
    <div id="app2">
      <h3>app2 인스턴스 영역</h3>
      <my-component></my-component>
      <my-local-component></my-local-component>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>

      Vue.component('my-component',{
        template : '<div>전역 컴포넌트가 등록되었습니다.</div>'
      });

      var cmp = {
        // 컴포넌트 내용
        template: '<div> 지역 컴포넌트가 등록되었습니다.</div>'
      };

      new Vue({
        el:'#app',
        components: {
          'my-local-component':cmp
        }
      });

      new Vue({
        el:'#app2'
      });
    </script>
  </body>
</html>

실행 화면입니다.

에러가 발생하였습니다. 이것은 app2 영역에서 지역 컴포넌트 태그를 인식하지 못하여 생기는 오류입니다.

 

전역 컨포넌트는 인스턴스를 새로 생서할 때마다 인스턴스에 components 속성으로 등록할 필요가 없이 한 번 등록하면 어느 인스턴스에서든지 사용할 수 있습니다. 반대로 지역 컴포넌트는 새 인스턴스를 생성할 때마다 등록을 해줘야 합니다.

728x90
반응형
728x90
반응형

간단한 화면부터 복잡한 화면까지, 멋진 화면을 만들기 위해서는 UI를 생각해 봐야합니다. 이를 설계라고 하는데,  인스턴스와 컴포넌트가 있어야 합니다. 이 두가지에 대해서 알아보도록 하겠습니다.

인스턴스와 컴포넌트를 레고에 비유한다면 인스턴스는 레고를 조립하는 기본 판을, 컴포넌트는 레고 블록을 의미한다.

뷰 인스턴스

뷰로 화면을 개발하기 위해 필수적으로 생성해야하는 기본 단위입니다. 인스턴스의 생성은 아래와 같은 형식으로 생성을 합니다.

new Vue({
...
});

위에서 new Vue() 로 인스턴스를 생성할 때 Vue를 생성자라고 합니다. Vue 생성자는 뷰 라이브러리를 로딩하고 나면 접근할 수 있습니다. 뷰로 개발할 때 필요한 기능들을 생성자에 미리 정의해 놓고 사용자가 그 기능을 재정의하여 편리하게 사용하도록 하기 위해서 입니다.

 

- 옵션

옵션 속성은 인스턴스를 생성할 때 재정의할 data, el, template 등의 속성을 의미합니다.

  • el : 뷰로 만든 화면이 그려지는 시작점을 의미, 뷰 인스턴스로 화면을 렌더링할 때 화면이 그려질 위치의 돔 요소를 지정해 주어야 한다.
  • template : 화면에 표시할 HTML, CSS 등의 마크업 요소를 정의하는 속성
  • methods : 화면 로직 제어와 관계된 메서드를 정의하는 속성
  • created : 뷰 인스턴스가 생성되자마자 실행할 로직을 정의할 수 있는 속성

- 유효 범위

뷰 인스터스를 생성하면 HTML의 특정 범위 안에서만 옵션 속성들이 적용되어 나타납니다.이것을 유효 범위라고 합니다. 인스턴스의 유효범위는 el 속성과 밀접한 관계가 있습니다. 아래는 new Vue()로 인스턴스를 생성하고 나서 화면에 인스턴스 옵션 속성을 적용하는 과정입니다.

뷰 라이브러리 파일 로딩 → 인스턴스 객체 생성 → 특정 화면 요소에 인스턴스를 붙임 → 인스턴스 내용이 화면 요소로 변관 → 변환된 화면 요소를 사용자가 최종확인

인스턴스의 유효 범위를 확인하기 위해서는 아래와 같이 유효 범위를 벗어나게 코딩을 해 보면 됩니다.

<div id='app'>

</div>
{{ message }}

인스턴스의 유효 범위는 el 속성으로 지정한 <div id='app'> 태그 아래 요소입니다. 위의 코드와 같이 {{ message }}가 유효범위 밖에 있으면 뷰에서 인식하지 못하기 때문에 화면에는 {{ message }} 그대로 출력됩니다.

 

- 라이프 사이클

인스턴스의 상태에 따라 호출할 수 있는 속성이 있습니다. 이것을 라이프 사이클 속성이라고 합니다. 그리고 라이프 사이클 속성에서 실행되는 커스텀 로직을 라이프 사이클 훅(hook)이라고 합니다. (옵션 부분에서 살펴본 created 와 같은 속성) 라이프 사이클 속성에는 총 8개가 있습니다. 

라이프 사이클 단계를 크게 나누면 인스턴스의 생성, 생성된 인스턴스를 화면에 부착, 화면에 부착된 인스턴스의 내용이 갱신, 인스턴스가 제거되는 소멸의 4단계로 이루어 집니다. 각 단계 사이에 라이프 사이클 속성 created, mounted, updated 등이 실행됩니다.

 

  • beforeCreate : 인스턴스가 생성되고 나서 가장 처음으로 실행되는 라이프 사이클 단계, data 속성과 method 속성이 아직 인스턴스에 정의되어 있지 않음. 화면 요소에도 접근 불가
  • created : beforeCreate 라이프 사이클 단계 다음에 실행되는 단계, data 속성과 method 속성에 정의된 값에 접근하여 로직을 실행할 수 있지만, 아직 인스턴스가 화면 요소에 부착되지 전이기 때문에 template 속성에 정의된 돔 요소로 접근 불가, 컴포넌트가 생성되고 나서 실행되는 단계이기 때문에 서버에 데이터를 요청하여 받아오는 로직을 수행하기 좋음.
  • beforeMount : created 단계 이후 template 속서에 지정한 마크업 속성을 render() 함수로 변환한 후 el 속성에 지정한 화면 요소에 인스턴스를 부착하기 전에 호출되는 단계, render()함수가 호출되기 직전의 로직을 추가하기 좋음
  • mounted : el 속성에서 지정한 화면 요소에 인스턴스가 부착되고 나면 호출되는 단계, 화면 요서에 접근이 가능하여 제어를 하는 로직을 수행하기 좋음.
  • beforeUpdate : el 속성에서 지정한 화면 요소에 인스턴스가 부착되고 나면 인스턴스에 정의한 속성들이 화면에 치환됨. 치환된 값은 뷰의 반응성을 제공하기 위해 $watch 속성으로 감시함. 이를 데이터 관찰이라함. 관찰하고 있는 데이터가 변경되면 가상 돔으로 화면을 다시 그리기 전에 호출되는 단계, 변경 예정인 새 데이터에 접근할 수 있어 변경 예정 데이터의 값과 관련된 로직을 미리 넣을 수 있음.
  • updated : 데이터가 변경되고 나서 가상 돔으로 다시 화면을 그리고 나면 실행되는 단계, 데이터 변경 후 화면 요소 제어와 관련된 로직을 추가하기 좋은 단계
  • beforeDestroy : 뷰 인스턴스가 파괴되기 직전에 호출되는 단계, 아직 인스턴스에 접근 가능, 뷰 인스턴스의 데이터를 삭제하기 좋은 단계
  • destoryed : 뷰 인스턴스가 파괴되고 나서 후출되는 단계, 뷰 인스턴스에서 정의한 모든 속성이 제거되고 하위에 선언한 인스턴스들 또한 모두 파괴됨

아래의 예제 코드를 통하여 라이프 사이클에 대하여 알아봅시다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Vue Instance Lifecycle</title>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message : 'Hello Vue.js!'
        },
        beforeCreate : function(){
          console.log("beforeCreate");
        },
        created:function(){
          console.log("created");
        },
        mounted:function(){
          console.log("mounted");
          this.message = "Hello typiler!"
        },
        updated:function(){
          console.log("updated");
        }
      });
    </script>
  </body>
</html>

 

위 코드를 실행한 결과는 아래와 같습니다.

개발자 도구의 Console 을 보면 뷰 라이프 사이클의 흐름대로 beforeCreate, created, mounted, updated 가 표시되는 것을 확인할 수 있습니다. updated는 mounted 에서 this.message 의 값을 변경하여 데이터 변경이 일어나 화면이 다시 그려지며 호출이 됩니다. 

728x90
반응형
728x90
반응형

넥사크로의 경우 사설 인증서의 통신을 허용하지 않아서 runtime 구동시 에러가 나타납니다. 그렇다고 개발환경을 위해서 ssl을 구매할 수 없습니다. 이럴때 아래의 설정을 통하여 사설 인증서의 통신을 허용할 수 있습니다.

  1. 내 컴퓨터에서 "C:\[사용자계정]\AppData\LocalLow\nexacro\17\nexacro.xml 파일을 메모장으로 열기합니다.
  2. setting 항목중에 SSLUnlock 항목을 "true"로 설정합니다.

간단한 설정으로 개발환경에서 사설인증서로 등록하여 통신할 수 있도록 세팅이 가능합니다.

728x90
반응형
728x90
반응형

넥사크로에서 그리드 셀에서 정보가 많을 경우 줄바꿈을 하여 표시를 해주는 경우가 종종 있습니다. 그리드 셀 안에서 줄바꿈(개행)을 할 수 있는 방법은 아래와 같습니다.

* Query 에서 줄바꿈 문자

select
    'aaaaa' || chr(10) || char(13) || 'bbbbbb' as cell 1
from dual

위 방법은 chr(10) 과 chr(13) 을 이용하여 데이터 자체에 개행문자를 삽입하여 주는 방식입니다.

* xfdl 에서 줄만꿈 문자

var newLine = String.formCharCode(13) + String.formCharCode(10);

var data = "aaaaa" + newLine + "bbbbb";

위 방법은 xfdl 에서 String.formCharCode 함수를 이용하여 10, 13 코드드를 불러내 개행문자를 넣어 주는 방식입니다.


728x90
반응형
728x90
반응형

파라매트릭 서치(Parametric Search)는 바이너리 서치와 매우 유사합니다. 차이점은 최적화 문제를 결정문제로 바꾸어 푸는 것입니다. 원하는 조건을 만족하는 가장 알맞는 값을 특정한 오차범위 이내에서 알고 싶은 경우에 사용을 합니다.

  • 바이너리 서치 : 배열에서 중앙값이 가리키는 값이 내가 찾는 값인지가 중요
  • 파라매트릭 서치 : 원하는 조건을 만족하는 가장 알맞는 값을 찾는 것

동작과정

  1. 데이터를 정렬한다.
  2. 범위를 반씩 좁혀간다.
  3. S 와 E 가 같을때 까지 진행한다.

 

시간복잡도

바이너리 서치와 같은 O( log N ) 입니다.

 

참고사이트

https://www.crocus.co.kr/1000
 

파라매트릭 서치(Parametric Search)

목차 1. 파라매트릭 서치(Parametric Search)란? 2. 예시를 통한 파라매트릭 서치(Parametric Search) 3. 시간 복잡도 4. 정리 5. 관련 문제 1. 파라매트릭 서치(Parametric Search)란? Parametric Search에 대해..

www.crocus.co.kr

https://en.wikipedia.org/wiki/Parametric_search
 

Parametric search - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search In the design and analysis of algorithms for combinatorial optimization, parametric search is a technique invented by Nimrod Megiddo (1983) for transforming a decision algorithm (does

en.wikipedia.org

 

기본코드

'#' 의 개수를 알아내는 문제

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;


class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    static char[] arr;
    
    static int parametricSearch(int s, int e){
    	
    	int maxIndex = -1;
    	
    	while(s<=e){
    		int mid = (s+e)/2;
    		char mVal = arr[mid];
    		
    		if (mVal == '#') {
                if (maxIndex < mid) maxIndex = mid;
                s = mid + 1;
            }
            else {
                e = mid - 1;
            }
    	}
    	
    	return maxIndex;
    	
    }
    
    public static void main(String[] args) throws IOException {      
    	
    	String str = "#######___";
   		arr = str.toCharArray();
  		
   		int cnt = parametricSearch(0, arr.length-1) + 1;
    		
   		bw.write(cnt+"\n");
    	
        br.close();
        bw.close();        
    }
}
728x90
반응형
728x90
반응형

바이너리 서치와 바이너리 서치 트리는 차이가 있습니다. 이중 오늘 공부할 내용은 바이너리 서치(Binary Search) 입니다. 자료구조가 아니라 알고리즘입니다. 바이너리 서치는 정렬되어있는 상태에서 내가 원하는 값을 찾고 싶을때 찾는 알고리즘 입니다. 여기서 정렬되어있는 상태가 중요합니다. 이것이 기본조건입니다. 데이터를 빨리 찾기 위한 방법입니다.

 

동작과정

  1. 데이터를 정렬한다.
  2. 범위를 반씩 좁혀가며 데이터를 찾는다.

 

시간복잡도

한번 탐색할때 마다 크기를 반으로 줄이기 때문에 시간복잡도는 O( log N ) 이 됩니다.

 

참고사이트

https://ko.wikipedia.org/wiki/%EC%9D%B4%EC%A7%84_%EA%B2%80%EC%83%89_%EC%95%8C%EA%B3%A0%EB%A6%AC%EC%A6%98
 

이진 검색 알고리즘 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 이진 검색 알고리즘(binary search algorithm)은 오름차순으로 정렬된 리스트에서 특정한 값의 위치를 찾는 알고리즘이다. 처음 중간의 값을 임의의 값으로 선택하여,

ko.wikipedia.org

 

기본코드

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.util.Arrays;


class 바이너리서치_기본코드 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    static int[] arr = {50,30,1,2,5,7,9,10};
    static int tar = 7;
    
    static void bSearch(int s, int e){
    	while(s<=e){
    		int mid = (s+e)/2;
    		int mVal = arr[mid];
    		
    		if(mVal == tar){
    			System.out.println("발견");
    			return;
    		}
    		
    		if(mVal < tar) s= mid + 1;
    		else e = mid - 1;
    	};
    	
    	System.out.println("미발견");
    }
    
    public static void main(String[] args) throws IOException {      
    	
    	// 바이너리 전제조건 => 정렬이 필수
    	Arrays.sort(arr);
    	
    	bSearch(0,arr.length-1);
    	
        br.close();
        bw.close();        
    }
}
728x90
반응형
728x90
반응형

◎ 개발 환경 설정

Vue.js 를 실행하기 위한 개발 환경 설정을 진행해 보도록 하겠습니다. 참고로 저는 제가 구매한 책을 기준으로 따하는데, 책에 나온 버전이 오래되어서 방법만 따라하고 버전은 되도록 최신 버전으로 설정을 하도록 하겠습니다.

일단, 필요한 도구는 아래와 같습니다.

  • 크롬 브라우저
  • 아톰(Atom) 텍스트 에디터
  • 노드제이에스(Node.js)
  • 뷰 개발자 도구(Vue.js devtools, 크롬 확장 플러그인)

 

- 크롬 브라우저 설치

크롬 브라우저는 웹 앱을 개발할때 좋은 브라우저로, 최신 웹 트렌드와 문법을 빠르게 반영하고 있는 브라우저 입니다. 웹 개발 시 편리한 기능을 제공하는 크롬 개발자 도구를 지원합니다. 공식사이트는 아래와 같습니다. 크롬 브라우저를 설치하여 줍니다.

https://www.google.co.kr/chrome/?brand=IBEF&gclid=CjwKCAjwiLGGBhAqEiwAgq3q_iYawp_Tue4teYkbz64iXJSD8JYImionS5TjwIUJuGKSJOom38uZ7BoCDpsQAvD_BwE&gclsrc=aw.ds 
 

Chrome 웹브라우저

더욱 스마트해진 Google로 더 심플하고 안전하고 빠르게.

www.google.com

다음으로 아톰 에디터를 설치합니다. 아톰은 깃허브에서 제작한 무료 텍스트 에디터 입니다. 또한, 확장 플러그인들을 이용하여 유용한 기능들을 추가할 수 있기 때문에 기능 면에서도 우수합니다. 

 

 - 아톰 설치

1. 아톰사이트에서 최신버전을 다운로드합니다.

https://atom.io/
 

A hackable text editor for the 21st Century

At GitHub, we’re building the text editor we’ve always wanted: hackable to the core, but approachable on the first day without ever touching a config file. We can’t wait to see what you build with it.

atom.io

 

2. 다운받은 파일을 실행하여 아톰을 설치한 후 실행하면 아래와 같은 화면이 나타납니다.

3. 편한 코딩을 위하여 테마를 설치합니다. 메뉴의 [File -> Setting] 을 선택하여 "Install" 탭을 클릭하면 테마를 설치할 수 있는 탭이 나타납니다. 검색하는 부분을 부면 "Themes" 버튼이 있습니다. 이 버튼을 클릭하고 검색창에 "seti-ui"를 입려하면 검색 결과나 나타납니다. 아래 화면에 표시된 "Install" 버튼을 클릭하여 테마를 설치합니다.

seti-ui 는 직관적인 파일의 아이콘을 제공하여 파일 구분이 쉽게합니다.

같은 방법으로 "atom-material-syntax-dark" 를 검색하여 설치합니다. 이 테마는 자바스크립트 코드 구문 강조색의 조합이 잘 되어 있어 코드의 가독성을 높여줍니다.

4. 설치한 테마를 적용하여 봅니다. [File->Setting] 에서 나오는 탭에서 "Themes" 을 눌러 UI Theme 드롭 다운 박스를 선택하여 설치한 "Seti"를 석탠합니다.  

마찬가지로 Syntax Theme 드롭 다운 박스를 클릭하여 "Atom Material Dark" 를 선택하여 적용합니다.

5. 아톰 패키지를 설치하여 개발에 유용한 기능들을 추가적으로 설치합니다. [File -> Setting]에서 Install 탭에 패키지 부분에 "language-vue" 로 검색하여 아래 보이는 것과 같은 것을 설치합니다. 패키지는 별도의 적용은 없으나 아톰 에디터를 재실행하여야 적용이 됩니다.

아톰 에디터를 재실행하고 새로운 파일 'Main.vue' 를 만듭니다. 그리고 생성된 파일에 tem을 입력하면 아래와 같이 자동 완성 기능이 표시됩니다. 이것을 선택하면 자동으로 기본 코드구조가 갖춰집니다.

 

- Node.js 설치

Node.js는 서버 사이드 자바스크립트로, 서버 측에서 실행되는 자바스크립트 실행 환경을 의미합니다. 뷰 CLI(Command Line Interface)를 이용하여 쉽게 뷰 프로젝트를 구성하려면 Node.js가 설치되어 있어야 합니다.

1. Node.js 사이트에서 설치파일을 다운로드 합니다. LTS 버전으로 다운을 합니다. Current 버전보다 안정적인 버전이라고 합니다.

https://nodejs.org/en/
 

Node.js

Node.js® is a JavaScript runtime built on Chrome's V8 JavaScript engine.

nodejs.org

2. 다운로드한 파일을 실행하여 설치를 진행하면 Node.js 와 Node 패키지 매니저(NPM, Node Package Manager)가 컴퓨터에 설치됩니다. 설치가 완료되었으면 명령 프롬프트에서 node -v 를 실행합니다. 정상적으로 설치가 되었다면 아래와 같이 Node.js 의 버전이 표시됩니다.

 

- 뷰 개발자 도구 설치하기

뷰 개발자 도구는 크롬 프러그인 입니다. 뷰로 개발할 때 도움을 주는 유용한 도구로, 뷰로 만든 웹 앱의 구조를 간편하게 디버깅하거나 분석할 수 있습니다. 

 

1. 구글에서 vue.js devtools 를 검색하여 Chrome 웹스토어 확장프로그램 "Vue.js devtools" 로 이동합니다. 화면에 보이는 "Chrome에 추가" 버튼을 클릭하여 설치합니다.

https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd
 

Vue.js devtools

Chrome and Firefox DevTools extension for debugging Vue.js applications.

chrome.google.com

프로그램을 설치하고 크럼 브라우저 주소창 오른쪽에 퍼즐 모양을 클릭하면 설치된 플러그인이 나타납니다.

 

◎ Hello Vue.js 프로젝트 만들기

개발 환경을 구성하였으면 뷰를 사용하여 간단한 메시지를 출력하는 프로젝트를 만들어 보겠습니다. 작업 순서는 아래와 같습니다. 

  1. HTML 파일 생성
  2. 뷰 소스 코드 추가
  3. 브라우저로 실행

아톰 에디터에서 편한 폴더 위치에 index.html 파일을 생하여 아래와 같이 코딩합니다.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <meta charset="utf-8">
    <title>Vue smaple</title>
  </head>
  <body>
    <div id="app">
      {{ message }}
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script>
      new Vue({
        el: '#app',
        data: {
          message : 'Hello Vue.js!'
        }
      });
    </script>
  </body>
</html>

위 코드는 html 기본 구조에 <div> 태그를 하나 추가하고, 뷰 라이브러리를 로딩한 후 뷰로 Hello Vue.js! 라는 간단한 메시지를 출력하는 코등입니다. index.html 을 브라우저로 실행하면 아래와 같은 화면이 나타납니다.

개발자 도구를 실행하여 코드를 확인하도록 합니다. 크롬에서 개발자 도구는 F12 키를 누르면 아래와 같이 나타납니다. 개발자 도구의 Console 탭을 클릭하면 두개의 로그가 나타납니다. 첫번째로그는 "뷰 크롬 익스텐션을 다운로드하라는 로그"입니다. 서버에서 띄운 것이 아니라 파일 시스템에서 접근하여 브라우저로 실행했기 때문에 나타나는 것이라고 합니다. 

이 부분을 해결하기 위하여 크롬 확정 플러그인 설정을 변경해야합니다. 크롬 브라우저의 메뉴에서 아래 경로의 [확장 프로그램]을 선택합니다.

아래와 같은 새로운 페이지가 열리고 설치된 확장 플러그인 목록이 표시됩니다. Vue.js devtools 의 세부 정보 버튼을 클릭합니다.

세부정보창에 나오는 메뉴중 "파일 URL에 대한 엑세스 허용"을 활성화 하여 줍니다.

그리고 다시 페이지를 실행하면 첫번째 로그가 사라져 있습니다.

개발자 도구에서 Vue 탭을 확인합니다. 페이지 가운데에 보이는 '<Root>=$0'을 클릭하면 왼쪽의 'Hello Vue.js!' 텍스트가 강조되면서 오른쪽에 루트 컴포넌트에 대한 상세 내용이 표시됩니다. 

화면상으로 표시된 'Hello Vue.js!' 텍스트는 최상위 컴포넌트의 data 속성인 message의 값이라는 것을 알 수있습니다. 

 

지금까지 개발 환경 설정 및 간단한 프로젝트까지 만들었습니다. 

728x90
반응형
728x90
반응형

Union-Find는 자료 구조입니다. 그래프 알고리즘에서 사용하는 대표 알고리즘입니다. 여러개의 노드가 존재할 때 두 개의 노드를 선택해서, 현재 이 두 노드가 서로 같은 그래프에 속하는지 판별하는 알고리즘입니다. Union-Find 알고리짐은 다른 고급 그래프 알고리즘의 베이스가 되니 반드시 학습하셔야 합니다.

 

동작과정

  • 파인드(Find) : 어떤 원소가 주어졌을 때 이 원소가 속한 집합을 반환한다. 파인트는 일반적으로 어떤 원소가 속한 집합을 '대표'하는 원소를 반환하는데, 이를 위해서 어떤 원소와 각 대표 원소들 간의 파인드 결과를 비교하여 같은 집합임을 판단한다.
  • 유니온(Union) : 두 개의 집합을 하나의 집합으로 합친다.

시간복잡도

평균적으로 트리의 높이마큼 탐색하는 O(logN) 입니다.

참고사이트

https://m.blog.naver.com/ndb796/221230967614
 

17. Union-Find(합집합 찾기)

Union-Find(유니온-파인드)는 대표적인 그래프 알고리즘입니다. 바로 '합집합 찾기'라는 의미를 가진 알...

blog.naver.com

https://ko.wikipedia.org/wiki/%EC%84%9C%EB%A1%9C%EC%86%8C_%EC%A7%91%ED%95%A9_%EC%9E%90%EB%A3%8C_%EA%B5%AC%EC%A1%B0
 

서로소 집합 자료 구조 - 위키백과, 우리 모두의 백과사전

위키백과, 우리 모두의 백과사전. 메이크셋은 8개의 개체를 생성한다. 유니온 연산을 여러 번 수행하면 여러 집합들이 합쳐진다. 컴퓨터 과학 분야 에서 서로소 집합(disjoint-set) 자료 구조, 또는

ko.wikipedia.org

 

기본코드

import java.io.*;
import java.util.Arrays;
import java.util.StringTokenizer;

class UnionFind_기본코드 {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));

    static char[] uArr = new char[100];

    static char getFind(char tar) {
        //최종보스가 누군지 리턴하는 함수        
        if (uArr[tar] == 0) return tar;        
        char ret = getFind(uArr[tar]);
        uArr[tar] = ret; //현재 보스를 최종보스로 교체
        return ret;        
    }

    static void setUnion(char t1, char t2)
    {
        char a = getFind(t1);
        char b = getFind(t2);
        if (a == b) return;
        uArr[b] = a;
    }

    public static void main(String[] args) throws IOException {        

        setUnion('A', 'B');
        setUnion('B', 'C');
        setUnion('E', 'D');        
        setUnion('F', 'E');        
        setUnion('G', 'H');        
        setUnion('I', 'J');        

        System.out.println("A:"+getFind('A'));
        System.out.println("B:"+getFind('B'));
        System.out.println("C:"+getFind('C'));
        System.out.println("D:"+getFind('D'));
        System.out.println("E:"+getFind('E'));
        System.out.println("F:"+getFind('F'));
        System.out.println("G:"+getFind('G'));
        System.out.println("H:"+getFind('H'));
        System.out.println("I:"+getFind('I'));
        
        //활용, A랑 E랑 같은 조직인지 확인하는 코드
        if (getFind('E') == getFind('D')) {
            System.out.println("같은조직");
        }
        else {
            System.out.println("다른조직");
        }

        br.close();
        bw.close();
    }
}
728x90
반응형

+ Recent posts