오늘 포스팅 할 내용은 Android LinearLayout과 비슷한 Java의 Swing LinearLayout Manager 입니다.


Java가 기본적으로 제공하는 레이아웃은 아래와 같습니다.


  "FlowLayout,  BorderLayout, GirdLayout, BoxLayout, GridBagLayout"


우리는 GUI를 만들때, 버튼이나 라벨같은 컴포넌트들이 수직 정렬로 배치 되는걸 선호 합니다.


만약 컴포넌트들을 수직 정렬로 배치한다면, 위 레이아웃 중 무엇을 선택해야 할까요?


하나씩 살펴보겠습니다.




FlowLayout


  FlowLayout은 가로 방향으로 하나씩 쌓아가면서, 가로 방향 공간이 없을 시, 한칸 내려서 다시 가로 방향으로 쌓습니다.


이 특징을 이용하여 우리는 컴포넌트의 가로 크기를 가로 크기를 창 가로 크기 만큼 잡았을 시, 수직 정렬을 구현 할 수 있습니다.


하지만, 컴포넌트의 가로크기를 창 크기만큼 잡아야 한다는 단점과, 창의 크기를 움직였을때, 가로에 남는 공간이 생긴다면 수직정렬이


깨지기도 합니다. padding 크기를 준다 하더라도, 각 컴포넌트에게 JPanel을 감싸야 하는 불편함이 있죠.





BorderLayout


  BorderLayout은 동서남북 가운데 방향에 컴포넌트를 넣을 수 있습니다. 수직 정렬로 쌓으려면 북, 가운데, 남 이렇게 3방향을 써야 하는데요


이렇게 3개의 공간뿐이 쓰질 못하니, 3개의 공간안에 또, JPanel을 배치한 후, 그 JPanel안에 또 컴포넌트를 쌓는 방법밖에 없습니다.


그리고 해보시면 알겠지만, 컴포넌트 사이즈를 원하게 조종하는것도 만만치 않습니다.




GridLayout


  GridLayout은 간단하면서도 짜증납니다. 그 이유는 수직정렬 자체는 쉽습니다.


다만,  GridLayout 레이아웃 특성상 모든 컴포넌트의 크기가 같습니다. 


모든 컴포넌트의 크기가 같아야 하는 경우도 있겠지만, 그런 경우는 흔치 않습니다.





BoxLayout, GridBagLayout


  BoxLayout, GirdBagLayout이 우리가 원하는 수직 정렬을 하기 위해 필요한 레이아웃이라 볼 수 있습니다. 


단점은 너무 어렵습니다.


BoxLayout은 제 개인적으로 사용해 본 결과 이상하게 오작동하며, 


특히 GridBagLayout은 GridBagConstraints라는 제약조건을 설정할 수 있는 객체와 함께 사용하는데, 사용 방법이 무척 어렵습니다.






LinearLayout


 간단한 수직정렬 조차 괜찮은 레이아웃이 없던 상황에, 안드로이드 프로그래밍을 할때 썼었던 LinearLayout이 생각났었습니다. 


있을땐 몰랐는데 없으니까, 참 쓰기 괜찮은 레이아웃 이였다는 생각이 들었습니다.


결국 직접 만들었습니다.  오픈소스로 제작했구요, 해당 URL 은 아래와 같습니다.


https://github.com/Mommoo/FlatSwing/tree/master/src/com/mommoo/flat/layout/linear


사용방법이 어려운건 선호하지 않기 때문에 최대한 간단한 방향으로 만들었습니다.


아래의 코드는 LinearLayout을 이용한 예시입니다.


예시는 전부 수직정렬만 보여주지만, 수평정렬도 가능합니다.


주석을 읽어보면 어렵지 않게 쓰실 수 있습니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
JPanel panel = new JPanel();
panel.setLayout(new LinearLayout(Orientation.VERTICAL, 15));
 
// 기본 컴포넌트 크기입니다.
panel.add(new JButton("Test1"));
 
// 설정한 방향과 상반되는 방향의 크기를 부모창 크기 만큼 맞춥니다.
panel.add(new JButton("Test2"), new LinearConstraints().setLinearSpace(LinearSpace.MATCH_PARENT));
 
// 기본 컴포넌트 크기에 가운데 정렬 입니다.
panel.add(new JButton("Test3"), new LinearConstraints().setLinearSpace(LinearSpace.WRAP_CENTER_CONTENT));
 
// 원하는 컴포넌트 크기입니다.
JButton button = new JButton("Test4");
button.setPreferredSize(new Dimension(300,200));
panel.add(button);
 
frame.setContentPane(panel);
frame.setVisible(true);
cs


아래의 스샷은 결과물 입니다.



또한 만든 LinearLayout은 멋진 Weight 속성을 줄 수 있습니다.


무게 속성을 이용한다면, 예쁘게 GUI배치를 할 수 있습니다.


아래의 코드를 참고하세요. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
JFrame frame = new JFrame();
frame.setSize(500,500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
JPanel panel = new JPanel();
panel.setLayout(new LinearLayout(Orientation.VERTICAL, 15));
 
// 기본 컴포넌트 크기에 무게 4만큼 차지 합니다.
panel.add(new JButton("Test1"), new LinearConstraints().setWeight(4));
 
// 설정한 방향과 상반되는 방향의 크기를 부모창 크기 만큼 맞추고, 무게 2만큼 차지 합니다.
panel.add(new JButton("Test2"), new LinearConstraints().setWeight(2).setLinearSpace(LinearSpace.MATCH_PARENT));
 
// 기본 컴포넌트 크기에 가운데 정렬이 진행되며 무게 1만큼 차지 합니다.
panel.add(new JButton("Test3"), new LinearConstraints().setWeight(1).setLinearSpace(LinearSpace.WRAP_CENTER_CONTENT));
 
// 원하는 컴포넌트 크기와, 무게 3만큼 차지합니다.
JButton button = new JButton("Test4");
button.setPreferredSize(new Dimension(300,200));
panel.add(button, new LinearConstraints().setWeight(3));
 
//총 무게는 4 + 2 + 1 + 3 = 10이므로, 각 컴포는트는 10에서 무게 크기 만큼 크기를 나눠 가집니다.
 
frame.setContentPane(panel);
frame.setVisible(true);
cs



아래의 스샷은 결과물 입니다.




오늘 포스팅은 여기까지 입니다. 


LinearLayout은 현재 만들고 있는 Swing 라이브러리에 있습니다. 


현재 제작중이라... 버그가 있을 수 있습니다. 


알려주시면 빠르게 수정 할 수 있으니, 알려주시면 감사하겠습니다.


좀더 많은 정보를 알고 싶으시면 아래의 URL을 참고해주세요. 


FlatSwing - https://github.com/Mommoo/FlatSwing (멋진 Flat디자인이 적용된 스윙 라이브러리)


감사합니다.

'Java' 카테고리의 다른 글

[Java] 파일 경로 처리하기.  (2) 2019.01.24
JAVA - JNI 사용하기  (2) 2017.09.02
JAVA - DownCasting(다운캐스팅)  (25) 2016.08.27
JAVA - HashMap key 구하기.  (1) 2016.08.25
JAVA - 변수 선언할때 m을 왜 붙일까?  (2) 2016.07.05

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

커스텀 화면이나, 애니메이션을 만들고 싶을때가 있다.


태그 조합으로 css 애니메이션, animate 함수를 써도 되지만,


Canvas 객체로 코딩하는 것도 방법이다.


Canvas 객체로 코딩을 하는 도중에 이미지 , 텍스트가 이상하게 깨져 나오는 현상을 접했다.


알고보니, Canvas는 자체 해상도를 가지고 있고, 화면에 그려지는 크기를 따로 가지고 있었다.


1
<canvas id="myCanvas" width="1920" height="1080" style="width : 300px; height : 300px"></canvas>
cs


위와 같이 해상도는 컴퓨터 해상도로 맞춰주고, 화면에 그려지는 크기를 300px, 300px로 설정했더니,


이미지나 텍스트가 깨져 나오는 현상이 사라졌다.

'Html5 & CSS3' 카테고리의 다른 글

Html5 & CSS3 - 브라우저 접두사(prefix)  (0) 2016.11.15

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

초창기에는 GCM으로 푸시 서버를 구현했다면, 


최근 구글은 Firebase 회사를 인수하면서 FCM(Firebase Cloud Message) 기술을 선보이게 됬습니다.


오늘 포스팅 할 내용은 안드로이드(클라이언트)의 FCM 설정에 관련된 내용입니다.



파이어베이스 프로젝트 생성하기



https://console.firebase.google.com/?hl=ko


위 URL에서 프로젝트를 추가합니다.


추가하는 과정에서 알려주는 Server API Key help, Sender ID: help 데이터는 따로 적어두셔야 합니다.



Google-service.json 파일 다운받기



추가한 Firebase 프로젝트에서 설정탭을 누릅니다.



오른쪽에 google-service.json을 다운 받습니다.



안드로이드 스튜디오에서 프로젝트 생성하기



안드로이드 프로젝트를 생성합니다. 안드로이드 프로젝트 패키지 이름은 Firebase에서 만든  패키지 이름과


동일하게 합니다.



다운 받은 google-service.json 파일을 Project 폴더- app 폴더 안에 넣습니다.




안드로이드 스튜디오 Gradle 설정하기



안드로이드 스튜디오에는 Gradle 파일이 두개 있습니다. 


app 폴더에 한개, Project 폴더에 한개 있습니다.


먼저 Project폴더에 있는 build.gradle 파일로 접근합니다.


아래와 같이 classpath 'com.google.gms:google-services:3.0.0' 를 작성합니다.


추가하시고, sync 해주세요.


다음으로, app 폴더에 있는 build.gradle 파일로 접근합니다.


맨 윗줄에, apply plugin: 'com.android.applicaiton' 이 적혀있습니다.


아래에 스샷 처럼 바로 아랫줄에 apply plugin: 'com.google.gms.google-services'를 작성해주세요.




다음으로 dependencies 지역에 아래 스샷 처럼 


compile 'com.google.firebase:firebase-messaging:9.6.1' 를 추가합니다.




다 추가하셨으면 Sync 해주세요.


여기까지 오류 없이 성공해야 합니다.

 

오류 없이 성공하셨다면 셋팅은 완료했습니다.


다음 게시글은 Firebase 구동을 위한 코드 작성을 포스팅 하겠습니다.


읽어주셔서 감사합니다.


포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

안녕하세요. Mommoo 입니다.


프로그래밍에 관한 일을 하다보면 많이 듣는 용어중 하나 인,

비즈니스 로직(Business Logic)에 대하여 포스팅 합니다.




영역 구분하기



홈페이지 회원가입으로 예를 들어봅시다.


유저는 회원가입 양식 폼에 회원정보를 작성하고, 회원가입 버튼을 누르면 회원가입이 진행됩니다. 


이 과정 중 아이디 중복 검사, 본인 인증, 비밀번호 재 검사 등 유저가 통과해야 할 것이 많습니다. 


유저는 단순한 버튼 클릭으로 아이디 중복인지 아닌지,


본인의 인증이 올바른지, 비밀번호 가 올바른지 등등을  홈페이지의 글이나, 다이얼로그로 확인합니다.


유저 입장에선 아무렇지 않게 확인하고 있는 것 들이지만, 


프로그래머는 위에 일련의 인증할 것들을 구현하기 위해서는 생각보다 많은 수고를 들입니다.

프로그래머 입장에 서서, 영역을 나누어 보겠습니다.


위의 아이디 중복 검사를 예시로 들자면,

프로그래머는 유저가 입력한 아이디가 회원 중 아이디를 중복으로 쓰고 있는지 검사하기 위해


데이터베이스를 조사합니다. 데이터베이스를 조사 후, 중복 아이디가 없다면 유저에게 페이지 속 글


또는 다이얼로그로 아이디를 사용해도 된다는 표시를 해줍니다.


여기서 크게 2영역으로 나눌 수 있습니다. 


하나는 중복 아이디가 있는지 없는지를 검사하기위한 일련의 과정들 ( 1번째 영역 )


나머지는,  유저에게 단순히 텍스트나 다이얼로그로 알려주는 것이 있습니다. ( 2번째 영역 )


2번째 영역은 흔히, Presentation 영역 혹은 View 영역 이라고 많이 불리우는데,


가공된 데이터를 단순히 표시만 해주는 것입니다. (ex 아이디가 중복됬습니다 표시, 비밀번호 재 검사를 실패 했습니다. 등등)


그 데이터 가공을 담당하는것이 1번째 영역 흔히들 Logic 영역, Model 영역이라 불립니다.



비즈니스 로직이란?



위에서 소개한 영역 2가지 중, 첫번째 영역에서의 코딩을 흔히, 비지니스 로직이라 부릅니다.


위의 아이디 중복찾기를 다시 예시로 들자면, 아래와 같은 비지니스 로직이 작성될 것입니다.


회원이 작성한 아이디 값 저장하기 -> 회원정보가 있는 데이터베이스 연결 ->

데이터베이스에 회원이 작성한 아이디 값이 있는지 Select 
-> 


회원의 아이디가 이미 있는지 없는지 여부를 데이터화 하여 저장 -> 


데이터베이스 연결 끊기 -> View영역에게 가공된 데이터 전달


이러한 비지니스 로직은 유저 눈엔 보이진 않지만, 유저가 바라는 결과물을 올바르게 도출하기 위해 코드로 짜여집니다.


즉, 프로그래머는 유저가 원하는 행위를 컴퓨터에게 잘 전달하기 위해서는 비즈니즈 로직을 잘 구상해야 한다는 의미입니다.

이처럼, 비지니스 로직은 프로그래밍에서 빠질 수 없는 요소이며, 응용 프로그램의 핵심이 됩니다.




비지니스 로직은 유저가 바라는 결과물을 코드로 옮기므로 코드가 자주 변경되므로, 코드 품질도 매우 중요합니다.


비지니스 로직이 정리되지 않고 이곳 저곳 산재 배치되면,


프로그래머는 코드 관리에 어려움을 느끼고, 개발을 어렵게 하는 요인이 될 수 있는 것입니다.


그로 인하여 생산성, 품질등이 저하 됩니다.








비즈니스 로직은 정말 중요하지만, 유지보수 와 확장성을 고려한 코딩을 하기란 쉽지 않습니다.


프로그래머들은, 조금 이라도 더 비즈니스 로직을 잘 작성하기 위해 


프로그래밍 아키텍쳐를 공부를 해야하는 이유가 아닐까 합니다.

( 예를들어, 웹에서 주로 쓰이지만 대중적인 MVC, 안드로이드 에서 인기를 얻고 있는 MVP등등 ) 

'용어정리 > 프로그래밍용어' 카테고리의 다른 글

절대경로, 상대경로란?  (7) 2018.12.06
형상관리의 개념과 이유  (0) 2017.11.01
DTO와 VO란?  (2) 2017.02.08
GET방식 과 POST방식  (32) 2016.12.10
컴포넌트(Component)란?  (8) 2016.10.20

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

오늘은 앞선 버블정렬 - 이론 포스팅에서 언급한 버븡절렬 개념을 토데로


코드를 만들려고 합니다. 


저번에 만들어 놓은 Sort 클래스를 상속 받아서 만들어 볼겁니다.


아래의 2개 포스팅을 참고하세요.


http://mommoo.tistory.com/65 - 버블정렬 이론 

http://mommoo.tistory.com/64 - Sort 클래스 설계



아래는 완성된 소스 입니다.




1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
public class BubbleSort extends Sort{
    private int version;
 
    public BubbleSort(int version){
        this.version = version;
        start();
    }
    
    /* Naming sort */
    @Override
    protected String getSortName() {
        if(version == 0 ) return "Normal Bubble Sort";
        else if(version == 1 ) return "Advance Bubble Sort";
        return "Bubble Sort";
    }
 
    @Override
    public void sort(){
        if(version == 0) normal();
        else if(version == 1) advance();
    }
 
    private void normal(){
        int size = DATA_LENGTH - 1;
        for(int i = 0 ; i < size ; size--){
            for(int index = 0 ; index < size; index++){
                /*
                   If the value of preceding array element is less than the value of target array element,
                   Swap two values
                */
                if(TARGET_DATA_ARRAY[index] > TARGET_DATA_ARRAY[index+1])
                    swap(index,index+1);
            }
        }
    }
 
    private void advance(){
        int size = DATA_LENGTH - 1;
        for(int i = 0 ; i < size ; size--){
            boolean isSwap = false;
            for(int index = 0 ; index < size; index++){
                /*
                   If the value of preceding array element is less than the value of target array element,
                   Swap two values
                   Any array element doesn't swap is that means already aligned.
                   So if isSwap variable is false, escape for-operator
                */
                if(TARGET_DATA_ARRAY[index] > TARGET_DATA_ARRAY[index+1]) {
                    isSwap = true;
                    swap(index,index+1);
                }
            }
            if(!isSwap) return;
        }
    }
}
 
cs




완성된 버블소트는 2가지 버전이 있습니다.


하나는 평범한 버블소트, 나머지는 개선된 버블소트 입니다.


Sort 클래스 덕분에, 지금 만드는 Bubble 소트는 sort 메서드에 로직을 기입하고,


생성자에서 start() 메서드만 사용해주면 끝입니다.


23번째의 normal() 메서드가 평범한 버블소트 로직입니다.


앞선 포스팅의 이론데로, 배열의 처음부터 끝까지 큰 숫자를 맨 뒤로 보낸후,


배열의 사이즈를 하나씩 줄여나가며, 그다음 큰숫자를 계속 뒤로 배치하는 방법입니다.


하지만 이 로직은, 배열의 사이즈가 0이 되기전에 이미 정렬이 완료되어 더이상 진행하지 않아도 되는 경우를 생각하지 않습니다.


하지만 개선된 버블소트는 만약 이미 정렬이 완료 되었다면 진행을 멈출수 있도록 로직이 구성되어있습니다.


37번째의 advance() 메서드가 개선된 버블소트 로직입니다.


이렇게 BubbleSort 클래스가 완성이 되었다면, 결과를 출력할 클래스를 하나 더 만들어야 합니다.


또한, 콘솔에 이쁘게 출력하기 위해 만든 클래스가 있습니다. 


해당 클래스는 따로 설명드리지 않고 그냥 잘 쓰셨으면 합니다.


아래에 2개의 클래스 코드가 있습니다.


SortRunner.java - 결과물 출력 클래스 (main 함수 위치)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Calendar;
 
/**
 * Created by mommoo on 2017-04-05.
 */
public class SortRunner {
    public static void main(String[] args){
 
        Sort[] sorts = new Sort[]{
                new BubbleSort(0),
                new BubbleSort(1)
        };
        
        /* Sort sort-objects */
        Arrays.sort(sorts);
 
        /* Create sort printing board */
        SortBoardMaker board = new SortBoardMaker(sorts);
 
        /* Write additional information */
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy. MM. dd. hh:mm");
        String author = "Author : Mommoo";
        String title = "Title : SortProject";
        String time = "Time : "+simpleDateFormat.format(Calendar.getInstance().getTime());
 
        /* Set additional information */
        board.setAdditionalInfo(new String[]{author,title,time,"Data Length : "+Sort.DATA_LENGTH});
 
        /* print board */
        System.out.println(board);
    }
}
cs




SortBoardMaker.java - 콘솔에 출력을 이쁘게 하기위해 만든 클래스


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
/**
 * Created by mommoo on 2017-04-18.
 */
public class SortBoardMaker {
    private final StringBuilder TOP_BOTTOM_BORDER_BUILDER = new StringBuilder();
    private final StringBuilder BLANK_LINE_BUILDER = new StringBuilder();
    private final StringBuilder CONTENT_BUILDER = new StringBuilder();
    private int textWidth;
    private String[] information;
 
    SortBoardMaker(Sort[] sorts){
 
        /* Make sort-object printing */
        for(int i = 0, size = sorts.length ; i < size ; i++){
            final int RANK = i+1;
            final String SORT_NAME = sorts[i].getRegulationSortName();
            final String SORT_TIME = sorts[i].getRegulationSpendTime();
            final boolean SORT_SUCCESS = sorts[i].isSortSuccess();
 
            CONTENT_BUILDER.append("##   ")
                    .append(RANK).append(".")
                    .append(" [ Name ] ")
                    .append(SORT_NAME)
                    .append(" [ Time ] ")
                    .append(SORT_TIME)
                    .append(" [ Sort Success ] ")
                    .append(SORT_SUCCESS)
                    .append("   ##")
                    .append("\n");
            /* Have to sub enter-character(\n) length */
            if(i == 0) textWidth = CONTENT_BUILDER.length() -1;
        }
 
        /* Make top and bottom line of board :  ################### */
        for (int i=0 ; i< textWidth ; i++ ) TOP_BOTTOM_BORDER_BUILDER.append("#");
 
        /* Make blank line of board : ##         ## */
        for (int i = 0 ; i < textWidth ; i++) BLANK_LINE_BUILDER.append(" ");
        BLANK_LINE_BUILDER.replace(0,1,"#");
        BLANK_LINE_BUILDER.replace(1,2,"#");
        BLANK_LINE_BUILDER.replace(textWidth - 2,textWidth - 1,"#");
        BLANK_LINE_BUILDER.replace(textWidth - 1,textWidth,"#");
 
    }
 
    public void setAdditionalInfo(String[] information){
        this.information = information;
    }
 
    @Override
    public String toString() {
 
        StringBuilder additionalInfo = new StringBuilder();
        StringBuilder tempBuilder = new StringBuilder();
        if (this.information != null){
            for(String info : this.information){
                tempBuilder.append(BLANK_LINE_BUILDER.toString());
                tempBuilder.replace(5,5+info.length(),info).append("\n");
                additionalInfo.append(tempBuilder.toString());
                tempBuilder.delete(0,additionalInfo.length());
            }
        }
 
        return tempBuilder
                .append(TOP_BOTTOM_BORDER_BUILDER).append("\n")
                .append(BLANK_LINE_BUILDER).append("\n")
                .append(additionalInfo)
                .append(BLANK_LINE_BUILDER).append("\n")
                .append(CONTENT_BUILDER)
                .append(BLANK_LINE_BUILDER).append("\n")
                .append(TOP_BOTTOM_BORDER_BUILDER)
                .toString();
    }
}
 
cs



SortRunner.java에서 main함수를 실행하면 아래와 같이 결과가 나옵니다.


본인이 원하는 정보를 수정 할 수 있게 클래스들을 작성하였으니, 알맞게 수정하시면 되겠습니다.




몇번 돌려보시면 확실히 개선된 버블소트가 항상 빠르게 나옵니다.


오늘 포스팅은 여기까지 입니다.


다음 코드 포스팅 역시, SortRunner 클래스와 Sort 클래스를 활용하여 선택정렬을 포스팅 할 예정입니다.


읽어주셔서 감사합니다.




포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee


안녕하세요. Mommoo 입니다.


오늘은 정렬 중에, 학습하기 쉬운 버블정렬에 대해 포스팅 합니다.


버블 정렬이 어떻게 진행되는지 gif파일로 만들어 봤습니다.


버블정렬?



물속에 있는 거품이 수면위로 보글보글 하게 올라오는 것처럼,


제일 무거운 원소가 배열의 최상단까지 올라가는 과정을 마치 거품이 올라가는 것과 같다 하여 


이름을 버블정렬이라 지었습니다.




버블정렬의 원리



만약 아래와 같은 배열이 있다고 가정해봅시다.


위의 배열을 내림차순으로 정렬 해보려고 합니다. (1 2 3 4 5 6)


버블정렬은 정렬이 안된 배열의 범위내에서, 서로 붙어 있는 배열 요소 2개씩 비교해 나갑니다.


붙어있는 배열요소 2개를 비교했을시, 큰쪽을 뒤쪽으로 배치 한후, 


처음 비교 요소중 2번째 요소와 다음 요소(3번째요소) 를 또 비교합니다. 마찬가지로 2개의 요소중 큰 요소를 배치하구요.


이런식으로 배열의 끝까지 비교를 했을시, 첫 배열범위에서 제일 큰 수가 맨 뒤로 배치 됩니다.


아래의 예시를 보시면 더욱 이해가 잘 될겁니다.




1세트를 마치게 되면 첫번째 배열 범위(1~6번째)에서 제일 큰 숫자인 6이 맨 뒤에 배치 됩니다.


또한, 1세트를 마치면 맨뒤에 요소 6은 정렬이 완료 된 상태 입니다. 따라서, 배열범위를 변경해야 합니다. (1~5번째로 변경)



아래는 2세트 에서의 예시 입니다.



2세트를 마치게 되면 바뀐 배열 범위(1~5번째)에서 제일 큰 숫자인 5가 배열 범위 맨 뒤에 배치됩니다.


또한, 맨뒤의 요소 5,6은 정렬이 완료 된 상태 이므로, 배열 범위를 변경합니다.(1~4번째로 변경)




이런식으로, 한세트가 끝나면, 배열 범위를 바꾼 후 2개씩 비교를 해 나가면, 배열 뒤쪽에서는 내림차순으로 정렬이 됩니다.


결과적으로, 버블정렬의 가장 큰 특징은 범위 내의 제일 큰 숫자를 뒤로 배치 하는 것과, 배열범위를 하나씩 줄여가는것 입니다.



지금까지의 설명을 읽고, 맨 위의 gif를 다시 본다면 재밌게 보실 수 있습니다!.



버블정렬의 성능


소트의 성능을 생각해볼때, 공간복잡도와 시간복잡도를 생각해보게 됩니다.


공간 복잡도는 말그데로, 배열만을 썻느냐, 아님 추가 배열을 썼느냐 등을 가리는 것이고


시간 복잡도는 정렬을 하는데 시간이 얼마나 소요 됬는지를 알아봅니다.


정렬은 공간 복잡도 보다, 시간 복잡도가 직결되므로 시간 복잡도만 알아볼것입니다.


시간복잡도는 보통 빅O 표기법으로 표시를 하는데,


빅O 표기법은 걸린시간의 최악의 경우만을 표기합니다. 


또한, 걸린 시간에서 부수적인 계산요소들은 생략하여 표기합니다.


버블정렬의 빅O 표기법을 구해보자면 아래와 같습니다.


만약 배열이 정렬 된 상태에서 정렬이 걸린시간을 생각하면, 한번만 비교해본후, 


정렬된걸 감지한후, 더이상 비교와 교환을 하지 않습니다. 


만약 배열의 크기가 n이라 하면, 교환은 한번도 이루어지지 않고, 비교만 (n번)합니다. (최선의 상황)


위의 배열 예시는 정렬이 하나도 되지 않은 최악의 상황입니다. 오히려 역으로 정렬된 상태입니다.


위의 배열은 비교를 n번 + n-1번 + n-2번 + n-3번 + n-4번 +.....+ 1번 하므로, 결국 n*(n+1)/2 의 비교횟수와


n*(n+1)/2의 교환 횟수를 가집니다. (최악의 상황


따라서 빅O 표기법의 조건중 하나인 최악의 상황 n*(n+1)/2으로 따지는데, 


이것을 아래와 같이 부수적인 계산요소들은 생략합니다.


따라서 빅O 표기법은 O(n^2) 입니다.


이는 앞으로 볼 정렬에 비교한다면, 느린편에 속합니다.


다음 포스팅은 버블정렬 - 자바코드 편을 포스팅 하겠습니다.


읽어주셔서 감사합니다.

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

안녕하세요. Mommoo 입니다.


앞으로 버블 정렬,선택 정렬, 삽입 정렬, 힙 정렬, 퀵 정렬을 만들어 볼텐데요,


이러한 정렬 들을 만들기 쉽게, 디버깅을 편하게 하기 위해 조상 클래스 Sort를 만들어 보고자 합니다.


기본목표는 아래와 같습니다.


    • 정렬들간의 비교분석을 위해 같은 배열 데이터를 참조하게 한다.
    • 데이터의 갯수만 변경하면 데이터가 갯수에 맞게, 랜덤값이 자동적으로 생성되게 한다.
    • 정렬들간의 비교를 위하여 공통된 행위 설계. ( sort할때 걸리는 시간, sort가 성공했는지 여부, 규격화된 디버깅 설계 등등...)
    • Comparable 인터페이스를 구현 해, Sort클래스를 상속받는 수 많은 정렬 클래스들이 시간 순으로 랭크화 하게 한다.


먼저 완성된 소스입니다.


특이점등을 설명해드리자면...


▶  6번의 DATA_LENGTH 변수는 추후에, 데이터 갯수를 표시하기 위해 public으로 공개했습니다.


▶  16번의 static 초기화 부분에서는 자동적으로 랜덤 값을 넣어주며, sort가 성공했는지 여부를 알기 위해

미리 sort된 배열도 하나 만들었습니다.


▶  각각의 자식 클래스마다 공통된 배열의 값을 참조를 해야하지만, 자식만의 배열을 가져야 하므로,

28번의 배열을 protected로 추가했습니다.


▶  36, 39번의 메서드는 각 자식 클래스마다 독립적인 내용이므로 자식에게 구현을 맡겼습니다.


▶  42번의 start 메서드는 자식 클래스가 start 메서드를 사용했을시, sort가 진행되고 sort 진행시간이 기록됩니다.

또한, 프린팅을 줄 맞춰서 예쁘게 하기위해, 프린팅 정보중 너비가 제일 긴 텍스트의 길이를 저장했습니다.


▶  58번의 swap 함수는 sort에서 빠지지 않는 swap기능을 미리 구현해놓았습니다.


▶  117번의 toString메서드는 자식 클래스의 소트가 진행됬을경우, 정보를 프린팅 하기위해 구현했습니다.


▶  129번의 compareTo 메서드는 Comparable을 구현하기위해 오버라이딩 했습니다. 추후에

자식클래스들을 시간순으로 정렬하기 위해 작성했습니다.


준비한 내용은 여기까지 입니다.


다음 포스팅은, 이러한 Sort 클래스를 상속받아 Bubble 소트를 만들어보겠습니다!

포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

  안녕하세요. Mommoo 입니다.


오랜만에 글을 쓰네요. 이전 포스팅들을 읽어보시면 아시겠지만, 


저의 문체(?) 중 하나는 높임말을 사용하지 않는 것이었는데요.


오늘 부로 생각이 바뀌었습니다.  이제부터는 높임말을 사용하려 합니다.




  서론이 길었는데요,


이번에 준비한 포스팅 들은 지금 보시는거 포함해서, 버블정렬, 선택 정렬, 삽입 정렬, 힙 정렬, 퀵 정렬 이렇게 


총 6개 정도가 될 예정입니다. 저도 많이 부족하지만, 초보자들이 쉽게 배울 수 있도록 포스팅 순서 배치와


내용의 질적인 측면을 신경을 많이 썼습니다.  아무쪼록, 저 포함해서 서로 다같이 공부 할 수 있는


기회가 됬으면 합니다.



 만들어진 자바 데이터 정렬 프로젝트의 결과물은 아래와 같습니다.




물론 코드도 공개를 하지만,


각 정렬이 무엇이며, 직접 짜보는 과정에서 배운 개념과 중요하다 생각하는 점 등을


포스팅으로 작성 할 예정입니다.



첫번째 포스팅은 버블 정렬 부터 입니다.


감사합니다.






포스팅이 도움 되셨다면, 커피 한잔 후원해주세요!
더 좋은 포스팅 작성에 큰 힘이 됩니다.

Buy me a coffeeBuy me a coffee

+ Recent posts