안드로이드 프로그래밍 중 텍스트를 출력시키고 싶다면 TextView를 사용해보세요.

TextView는 View클래스를 상속받아 만들어진 클래스입니다.


※ 참고

만약 유저가 수정할 수 있는 텍스트란을 원하신다면 EditText를 사용해보세요.


XML Layout에서 기본적인 사용법입니다.


<TextView

android:layout_height="wrap_content"

android:layout_width="wrap_content"

android:id="@+id/text_view_id"

android:text="Hello World!" />


layout_height와 width는 텍스트뷰의 크기를 지정해 줍니다. wrap_content는 텍스트 뷰 내용에 맞게 맞춰진다는 뜻입니다.

id는 현재 텍스트뷰에 이름을 붙여준다고 생각합시다.(다른 누군가가 부를때 이름이 없으면 부를수가 없겠죠?)

text는 텍스트뷰에 표시 될 텍스트(문구)를 적습니다.


실행한다면 화면 좌측 상단에 Hello World!라고 작게 찍히는 모습을 확인 할 수 있습니다.


MainActivity로 가서 onCreate 함수 안에 다음과 같이 작성해봅시다.


TextView textView = (TextView) findViewById(R.id.text_view_id);

textView.setText("World Hello!");


TextView의 객체를 선언해주고 값을 findViewById 함수를 통해 XML에서 설정해주는 id(텍스트뷰의 이름)로 정의합니다.

그리고 setText함수를 통해 출력 될 텍스트를 설정하거나 바꿀 수 있습니다.


다음은 XML TextView attributes(속성)입니다.


autoText : 스펠링 검사를 자동으로 수행합니다.

cursorVisible : 텍스트 뷰의 커서를 보일지 설정합니다.

digits : 텍스트뷰에 숫자만 입력하도록 설정합니다.

editable : 텍스트뷰의 텍스트를 수정할 수 있는지 설정합니다.

ems : 텍스트뷰의 기본 길이를 설정합니다.

gravity : 텍스뷰의 텍스트가 나타날 위치를 지정합니다.

height : 텍스트뷰의 높이를 설정합니다.

hint : 텍스트 뷰가 비어있을 때 나타날 문자를 설정합니다.

inputType : 텍스트 뷰에 입력 될 텍스트의 입력 타입을 설정합니다.

- numeric : 숫자만 입력합니다.

- password : 입력된 숫자를 *로 표기합니다.

- phoneNumber : 휴대폰 번호 입력.

lines : 텍스트 뷰의 줄(라인)을 설정합니다.

maxEms : ems의 최대 길이를 설정합니다.

maxHeight : 텍스트 뷰의 최대 높이를 설정합니다.

maxLength : 텍스트 뷰에 입력 될 텍스트의 최대 길이를 설정합니다.

maxLines : 텍스트 뷰의 최대 줄 수를 설정합니다.

maxWidth : 텍스트 뷰의 최대 너비를 설정합니다.

※ min은 모두 최소값을 설정하는 속성입니다.

textColor : 텍스트 뷰에 입력 될 텍스트의 색깔을 설정합니다.

textSize : 텍스트 뷰에 입력 될 텍스트의 크기를 설정합니다.


다음은 Acitivity(Java class)에서 사용되는 TextView Class Public Methods(함수)입니다. 

getHint() : 텍스트 뷰에 설정된 hint 내용을 반환합니다.

setHint("hint") : 텍스트 뷰에 "hint"를 설정합니다.

getInputType() : 텍스트 뷰에 설정된 InputType을 반환합니다.

setInputType(int) : 텍스트 뷰의 입력 타입을 설정합니다. (type은 EditorInfo.inputType에 정의되어 있습니다.)

getLineCount() : 현재 입력된 텍스트 뷰의 라인 수를 반환합니다.

getMaxEms() : 텍스트 뷰의 최대 ems를 반환합니다.

setMaxEms(int) : 텍스트 뷰의 최대 ems를 설정합니다.

getMaxHeight() : 텍스트 뷰의 최대 높이를 반환합니다.

setMaxHeight(int) : 텍스트 뷰의 최대 높이를 설정합니다.

getMaxLines() : 텍스트 뷰의 최대 라인 수를 반환합니다.

setMaxLines(int) : 텍스트 뷰의 최대 라인 수를 설정합니다.

getMaxWidth() : 텍스트 뷰의 최대 너비를 반환합니다.

setMaxWidth(int) : 텍스트 뷰의 최대 너비를 설정합니다.

getText() : 텍스트 뷰에 입력된 텍스트를 반환합니다.

setText("text") : 텍스트 뷰에 "text"를 출력하도록 설정합니다.

append("text") : 텍스트 뷰에 "text"를 덧붙여 씁니다. (기존에 존재하던 텍스트 바로 뒤에 붙여서 입력됩니다.)

getTextSize() : 텍스트 뷰의 텍스트 크기를 반환합니다.

setTextSize(int) : 텍스트 뷰의 텍스트 크기를 설정합니다.


TextView에 대해 더 궁금한 사항이 있으시면 여기를 확인하세요.


2018/08/20 - [Language/Android] - 안드로이드 EditText 사용법 정리

2018/08/20 - [Language/Android] - [Android] 안드로이드 키보드 입력 창 올리기/ 내리기



정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.




C언어 프로그래밍에서 코드를 작성하다보면 무작위의 숫자가 필요한 경우가 존재합니다.

보통 무작위 숫자를 난수라고 표현합니다.

C언어에서 난수를 표현하기 위해서는 라이브러리를 사용해야합니다.


※ 알고가기

라이브러리란 자주 사용하는 함수들을 미리 작성하여 저장해둔 파일로써 보통 헤더파일로 저장됩니다.

이 헤더파일은 #include 라는 코드를 통해 추가해 줄 수 있는데

C언어에서 기본적으로 사용하는 헤더파일은 stdio.h 이며 이는 Standard Input Ouput(표준 입출력)의 약자입니다.

사용방법은 프로그램 코드 맨 윗줄에 #include <헤더파일명.h> 또는 "헤더파일명.h" 으로 사용할 수 있습니다.

보통 < > 는 Standard Library Header에서 사용하며 " "는 User Defined Header를 사용할 때 쓰는것이라 알려져있는데 크게 틀린말은 아닙니다.

< >와 " "의 차이는

- < > : 컴파일러가 미리 정해놓은 위치에서 헤더파일을 찾습니다.

- " " : 컴파일러가 미리 정해놓은 위치에서 헤더파일을 찾고 만약 찾지 못한다면, < >로 바꾸어 헤더파일을 찾습니다.

로 생각하면 되겠습니다. 결국 Header파일을 읽은 것인지 Source파일을 읽을 것인지에 따라 사용을 구분하면 되겠습니다.


다시 본론으로 와서, C언어에서 난수를 만들기위해서는 rand()라는 함수를 사용하면 됩니다.

rand()함수는 stdlib.h 헤더파일에 포함되어있기 때문에 코드 맨 윗줄에 #include <stdlib.h>를 작성해 줍니다.


☞ rand()함수 사용법

#include <stdio.h>

#include <stdlib.h> // rand() 함수 포함 라이브러리


int main()

{

int random = 0; // 정수형 변수 선언

for (int i = 0; i < 10; i++) { // 10번 반복

random = rand()%9; // 난수 생성

printf("%d\n", random); // 출력

}

}


☞ 실행결과


8번째 줄을 보시면 random = rand()%9; 라는 코드가 있습니다.

해석하면 rand() 함수에 의해 난수를 생성하고 그 숫자를 9로 나눈 나머지를 random 변수에 대입하는 코드입니다.


※ 알고가기

rand() 함수에 의해 생성되는 난수 : 0 ~ 32767


rand() 함수에 의해 생성된 난수를 9로 나눈 나머지(%)의 값은 0부터 8까지입니다.

이를 1부터 9까지 난수를 생성하고 싶을때는 다음과 같이 8번째 줄 코드를 변경합니다.


random = rand()%9 + 1;


이는 0부터 8까지 반환되는 난수에 1을 더해줌으로써 1부터 9까지 반환할 수 있도록 하는 코드입니다.


하지만 여기서 문제점이 발생합니다.

분명 개발자가 원하는 난수를 생성하고 출력했지만 그 패턴(규칙)이 매번 일정하다는 겁니다.



다시말해, 프로그램 실행 시(또는 반복문) 항상 같은 난수가 생성된다는 겁니다.

이는 진정한 난수라고 말할 수 없죠.

그렇다면 프로그램 실행 시 매번 다르게 난수를 생성하는 방법은 무엇일까요?


그건 바로 srand()라는 함수를 사용하면 됩니다!

rand() 함수를 사용하기 전에 다음과 같은 코드를 추가합니다.


srand(time(NULL));


무슨뜻이냐면 srand()함수는 rand()라는 함수에 무작위의 시드값을 주기위한 함수이며 그 파라미터로 time(NULL)이라는 매개변수를 전달합니다.

time(NULL)은 1970년 1월 1일 이후 경과된 시간을 초 단위로 반환하는 함수입니다.

이로써 1초 단위로 매번 다른 시드값을 생성해 rand()함수를 호출하는 것입니다.

이해가 안가시는분은 그냥 이걸 써야 진정한 난수가 생성되는구나! 라고 생각하시면 됩니다.

물론 time()함수를 사용하기 위해서 #include <time.h>를 추가해주시는걸 잊지마세요!


☞ 진정한 난수 생성코드

#include <stdio.h>

#include <stdlib.h> // rand()함수 포함 라이브러리

#include <time.h> // time()함수 포함 라이브러리


int main()

{

srand(time(NULL)); // 매번 다른 시드값 생성

int random = 0; // 정수형 변수 선언

for (int i = 0; i < 10; i++) { // 10번 반복

random = rand()%9; // 난수 생성

printf("%d\n", random); // 출력

}

}


☞ 실행결과


3번 실행 한 결과 모두 다른 난수값이 생성되는것을 확인 할 수 있습니다!

이로써 진정한 난수 생성하는 방법 및 코드에 대해 알아보았습니다.





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.



'C, C++' 카테고리의 다른 글

C/C++ 구조체 사용법 및 예제  (1) 2018.10.08
C/C++ 배열 사용법  (0) 2018.10.05
C 파일처리  (0) 2018.10.02
C++ 벡터 사용법  (2) 2018.09.26
C언어 포인터  (8) 2018.09.25
C++ 자바 상속 비교  (0) 2018.09.08
C++ String 문자열 사용법 정리  (0) 2018.08.20
[C++] C# 연동하기 / C# dll 파일 만들기  (1) 2018.08.18

자바 배열 사용법



배열이란 같은 데이터 타입을 가진 연속된 메모리 공간으로 이루어진 자료 구조입니다. 같은 데이터 타입을 가진 여러개의 변수를 할당하기위해 사용합니다.


자바에서 배열 사용하는 방법입니다.


1. 1차원 int형 배열

C/C++과 달리 자바는 모든 변수가 객체(Object)로 이루어져있기 때문에 배열을 사용하기 위해 배열 객체에 new를 통해 메모리 공간을 할당해줍니다.

다음은 1차원 int형 배열의 사용방법입니다.


소스코드(Java) - 1차원 int형 배열 선언

int arr[];

arr = new int[10]; // int arr[] = new int[10] 과 같음

// int arr[] = {1, 2, 3, 4} 도 가능


for(int i = 0; i < 10; i++) {

arr[i] = i+1;

}


System.out.print("arr = [ ");

for(int i = 0; i < 10; i++) {

System.out.print(arr[i]);

System.out.print(" ");

}

System.out.println("]");

실행결과


2. 1차원 String형 배열

int와 마찬가지로 String 배열 역시 똑같은 방법으로 선언하고 사용하시면 됩니다.

소스코드(Java) - 1차원 String형 배열 선언

String[] str = new String[10];


for(int i = 0; i<10; i++) {

str[i] = "str" + (i+1);

}


for(int i =0; i < 10;i ++) {

System.out.print(str[i] + " ");

}

실행결과


3. 1차원 int형 배열의 다른 선언방법

C/C++ 등의 언어에서는 배열을 선언과 동시에 크기를 지정해주어야 하지만 자바와 같은 언어의 경우 배열 객체의 선언과 정의를 따로함으로써 배열의 크기를 받아 지정해 줄 수 있습니다.(C/C++의 포인터 동적할당 처럼 사용)

소스코드(Java) - 1차원 int형 배열 선언2

int arr[];

int arr_size = 8;

arr = new int[arr_size];

for(int i = 0; i < arr_size; i++) {

arr[i] = i+1;

}


for(int i = 0; i < arr_size; i++) {

System.out.println(arr[i]);

}

실행결과


4. 2차원 int형 배열

1차원과 마찬가지로 new를 통해 선언할 수 있습니다.

소스코드(Java) - 2차원 int형 배열 선언

int matrix[][] = new int[5][5]; // 다음과 같이 초기화 할 수 있습니다.


for(int i = 0; i < 5; i++) {

for(int j = 0; j < 5; j++) {

matrix[i][j] = (j+1)+(i*5);

}

}


for(int i = 0; i < 5; i++) {

for(int j = 0; j < 5; j++) {

System.out.print(matrix[i][j] + " ");

}

System.out.println();

}

실행결과


5. 배열 복사

System.arraycopy 메소드를 통해 같은 데이터 타입의 배열끼리 배열을 복사 할 수 있습니다.

소스코드(Java) - 1차원 String형 배열 복사

String[] str1 = {"a", "b", "c"};

String[] str2 = new String[3];


System.arraycopy(str1, 0, str2, 0, 3); // 복사할 배열, 복사할 배열의 시작위치, 복사받을 배열, 복사받을 배열의 시작위치, 배열크기


for(int i = 0; i < 3; i++) {

System.out.println(str2[i]);

}

실행결과


6. 배열 정렬

Array클래스의 sort메소드를 통해 배열을 오름차순 또는 내림차순, 인덱스를 지정해서 배열의 요소를 정렬할 수 있습니다. (시간복잡도는 O(n logn))

소스코드(Java) - 1차원 int형 배열 정렬

int arr[] = {4, 2, 3, 1, 0}; // 배열의 선언과 동시에 초기화(크기는 알아서 지정)


Arrays.sort(arr, 0, 5); // 배열, 정렬을 수행 할 시작위치, 끝위치


for(int i = 0; i < 5; i++) {

System.out.println(arr[i]);

}

실행결과


이상입니다.




정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.





이진 힙


이진 힙은 다음 특징(Properties)을 가진 이진 트리입니다.

1. 완전 트리(Complete Tree)이며 배열(Array)안에 저장되기 적합(Suitable)합니다.

2. 이진 힙은 최소(Min) 힙 또는 최대(Max) 힙 중 하나입니다. 최소 힙에서 루트 노드의 값은 모든 노드의 값중 가장 작은 값이며, 최대 힙에서 루트 노드의 값은 모든 노드의 값중 가장 큰 값입니다.


이진 힙의 표현

이진 힙은 완전 이진 트리(Complete Binary Tree)입니다. 이진 힙은 일반적으로(typically) 배열로 표현 됩니다.


루드 노드는 Arr[0] - 배열의 첫번째 요소가 됩니다.

부모 노드의 표현 - Arr[(i-1)/2] 

좌측 자식 노드의 표현 - Arr[(2*i)+1]

우측 자식 노드의 표현 - Arr[(2*i)+2]


이진 힙 배열의 순회 순서는 너비(Level) 순서입니다.


힙의 활용

1. 힙 정렬(Heap Sort) : 힙 정렬은 O(nLog n) 시간 복잡도를 가지는 배열의 정렬 방법입니다.

2. 우선순위 큐(Priority Queue) : 우선순위 큐는 O(log n)의 시간 복잡도를 가지는(삽입, 삭제 등)  이진 힙을 효율적으로 사용할 수 있습니다.

3. 그래프 알고리즘(Graph Algorithm) : 그래프 알고리즘에 우선순위 큐를 효과적으로 사용 할 수 있습니다.


최소 힙의 구현 - 소스코드(C++)

class MinHeap
{
    int *harr; // 힙 요소 포인터
    int capacity; // 최소 힙의 최대 크기
    int heap_size; // 최소 힙의 현재 크기
public:
    MinHeap(int capacity); // 생성자
 
    void MinHeapify(int);
    int extractMin(); 

    int parent(int i) { return (i-1)/2; } // 부모 노드 반환
    int left(int i) { return (2*i + 1); } // 좌측 자식 노드 반환
    int right(int i) { return (2*i + 2); } // 우측 자식 노드 반환
 
    void decreaseKey(int i, int new_val); 
 
    int getMin() { return harr[0]; } // 가장 작은 값(루트 노드) 반환
 
    void deleteKey(int i);
    void insertKey(int k);
};
 
MinHeap::MinHeap(int cap) // 생성자
{
    heap_size = 0;
    capacity = cap;
    harr = new int[cap];
}
 
void MinHeap::insertKey(int k) // 노드 추가
{
    if (heap_size == capacity)
    {
        cout << "\nOverflow: Could not insertKey\n";
        return;
    }
 
    heap_size++; // 사이즈 증가
    int i = heap_size - 1; 
    harr[i] = k;
 
    while (i != 0 && harr[parent(i)] > harr[i]) // 자신의 위치를 검색
    {
       swap(&harr[i], &harr[parent(i)]);
       i = parent(i);
    }
}
 
void MinHeap::decreaseKey(int i, int new_val)
{
    harr[i] = new_val;
    while (i != 0 && harr[parent(i)] > harr[i])
    {
       swap(&harr[i], &harr[parent(i)]);
       i = parent(i);
    }
}
 
int MinHeap::extractMin()
{
    if (heap_size <= 0)
        return INT_MAX;
    if (heap_size == 1)
    {
        heap_size--;
        return harr[0];
    }
 
    int root = harr[0];
    harr[0] = harr[heap_size-1];
    heap_size--;
    MinHeapify(0);
 
    return root;
}
 
void MinHeap::deleteKey(int i)
{
    decreaseKey(i, INT_MIN);
    extractMin();
}
 
void MinHeap::MinHeapify(int i)
{
    int l = left(i);
    int r = right(i);
    int smallest = i;
    if (l < heap_size && harr[l] < harr[i])
        smallest = l;
    if (r < heap_size && harr[r] < harr[smallest])
        smallest = r;
    if (smallest != i)
    {
        swap(&harr[i], &harr[smallest]);
        MinHeapify(smallest);
    }
}





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.


'자료구조, 알고리즘' 카테고리의 다른 글

[BOJ] 8979 올림픽 - 문제 풀이  (1) 2019.03.29
정렬 알고리즘 종류  (0) 2018.09.12
검색 알고리즘 종류  (2) 2018.09.11
자료구조 그래프(Graph)  (1) 2018.09.06
자료구조 이진 탐색 트리(Binary Search Tree)  (0) 2018.09.01
자료구조 트리(Tree)  (0) 2018.08.30
[자료구조] 큐 QUEUE  (0) 2018.08.19
[자료구조] 스택 STACK  (0) 2018.08.19


안드로이드 OpenCV의 findContours 사용중 다음과 같은 오류가 발생했을 때 해결하는 방법입니다.

오류 :

Caused by: CvException [org.opencv.core.CvException: cv::Exception: OpenCV(3.4.3) /build/3_4_pack-android/opencv/modules/imgproc/src/contours.cpp:199: error: (-210:Unsupported format or combination of formats) [Start]FindContours supports only CV_8UC1 images when mode != CV_RETR_FLOODFILL otherwise supports CV_32SC1 images only in function '_CvContourScanner* cvStartFindContours_Impl(void*, CvMemStorage*, int, int, int, CvPoint, int)'


오류가 나는 이유는 findContours의 입력 값과 출력 값의 데이터 옵션 값이 다르기 때문입니다.


해결 방법 : 

Imgproc.findContours를 호출하기 전

기존의 Mat result 객체를 다음과 같이 처리해줍니다.

Imgproc.cvtColor(src, result, Imgproc.COLOR_BGR2GRAY, 1);


오류해결!


* 참고

문자인식 중 findContours가 이진화(threshold) 된 이미지의 개체들의 blob을 찾지 못할 때 : 이진화 된 이미지의 픽셀 값(색상)을 모두 반전 시켜줍니다.

코드 : 

for(int x=0; x<roi.getWidth(); x++) {

    for(int y=0; y<roi.getHeight(); y++) {

        if(roi.getPixel(x, y) == -1) {

            roi.setPixel(x, y, 0);

        }

        else {

            roi.setPixel(x, y, -1);

        }

    }

}





정보가 유익하셨다면 아래 공감버튼 눌러주시면 감사하겠습니다.

질문사항은 댓글로 달아주시면 성의껏 답변해드리겠습니다.



to Top