좌표평면에서 x와 y좌표가 주어졌을 때 그 점이 x축과 이루는 각을 구해보자


환경

  • C, C++
  • 삼각함수 및 역함수에 대한 이해


tangent란?

기본적으로 삼각함수를 알고 있다는 가정하에 x,y좌표가 주어졌을 때 x축과 이루는 각을 θ라고 하면 다음과 같이 tan(θ) = y/x라고 볼 수 있습니다.


atan(arctangent)란?

그렇다면 θ를 구할 때는 위에 있는 tan(θ) = y/x에 대해서 역함수를 취해주면 각 θ를 구할 수 가 있게됩니다.

그 역함수가 arctangent이며 tan-1(x)=arctan(x)=atan(x)=θ로 표현합니다.


C언어에서 atan2()를 이용해서 각도 구하기

C언어에서 atan()atan2()가 있지만 atan2()-π부터 π까지이기 때문에 즉, 음의 값 또한 표현 가능하기 때문에 atan2()를 사용한 예제입니다.

return 값들은 Radian 값이기 때무에 각도를 구하려면 180/π를 곱해줘야 합니다.

HelloWorld.c


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define PI 3.1415926535

double getDegree(double y, double x){
   return atan2(y,x) * 180 / PI;
}

int main()
{
   printf("%lf\n", getDegree(1,1));
   printf("%lf\n", getDegree(1,-1));
   printf("%lf\n", getDegree(-1,1));
   printf("%lf\n", getDegree(-1,-1));

    return 0;
}


결과는 아래와 같습니다.

Result

C언어의 stdlib.h에서 제공하는 정렬함수인 qsort를 사용해보자


환경

  • C언어 및 컴파일러


Quick Sort란?

원리

  • pivot을 정하고 pivot보다 작은 값들을 pivot의 왼쪽 pivot보다 큰 값들은 pivot의 오른쪽으로 위치시키고 pivot의 왼쪽 값들과 오른쪽 값들을 각각 따로 또 재귀를 통해 분할정복한다.

특징

  • O(nlogn)의 성능을 보이는 정렬 알고리즘중에 하나로 최악에는 O(n^2)의 성능을 보이지만 일반적으로 빠른 성능을 나타내기에 보편적으로 많이 쓰는 알고리즘 입니다.
  • Divide and Conquer이라는 분할정복 방법으로 정렬을 진행하며 자세한 부분은 다음을 참고하시면 좋습니다.
  • in-place sorting : 정렬 할 원소들을 위한 추가적인 메모리를 사용하지 않고 현재 메모리에서 정렬을 진행


C에서 Quick Sort인 qsort함수 사용하기

기본 구조

기본적으로 stdlib.h에서 Quick Sort 함수인 qsort 함수를 제공해주며 아래와 같습니다.


void qsort (void *base, size_t nel, size_t width, int (*compare)(const void *, const void *);

  • base : 정렬하고자 하는 배열의 포인터입니다.
  • nel : 배열의 각 원소들의 총 수입니다.
  • width : 배열에서 원소 하나의 크기입니다.
  • (*compare) : 비교를 수행할 함수 포인터입니다. C언어에서는 함수를 선언하고 구현한 후에 다음처럼 포인터로 특정 함수를 지정할 수 있습니다.

비교 함수에 대해서

4번째 인자에 대해서 조금 더 자세히 설명하면 비교함수 내부에는 1, 0 , -1중에 하나를 반환해야합니다. 만약 오름차순으로 정렬을 하고 싶다면 비교함수 내부에서 첫번째 변수가 두번쨰 변수보다 클 때 1첫번째 변수가 두번째 변수보다 작을 때 -1같을 때 0을 반환하도록 작성하면 됩니다. 물론 내림차순의 경우 1과 -1을 반환하는 부분의 등호를 바꾸어주면됩니다.


예제 코드

예제 코드는 아래와 같습니다.

HelloWorld.c

#include <stdio.h>
#include <stdlib.h>

// 오름차순으로 정렬할 때 사용하는 비교함수
int static compare (const void* first, const void* second)
{
    if (*(int*)first > *(int*)second)
        return 1;
    else if (*(int*)first < *(int*)second)
        return -1;
    else
        return 0;
}

int main()
{
    int arr[] = {32, 11, 97, 42, 21, 70, 56, 67, 88, 100};
    int array_size = sizeof(arr) / sizeof(int);
    int i;

    // 정렬 전
    for (i = 0; i < array_size; i++) printf("%d ", arr[i]);
    printf("\n");

    qsort(arr, array_size, sizeof(int), compare);

    // 정렬 후
    for (i = 0; i < array_size; i++) printf("%d ", arr[i]);
    printf("\n");

    return 0;
}


결과는 아래와 같습니다.

Result

XOR 연산을 자기자신 혹은 0과 했을 때 어떠한 결과가 나타나는지 알아보자


XOR 연산이란?

XOR 연산이란 bit단위에서는 아래의 예시처럼 서로의 비트가 다르면 1 같으면 0의 결과를 나타내는 연산자입니다.

1^1 = 0
1^0 = 1
0^1 = 1
0^0 = 0


XOR 연산을 자신과 했을 때

XOR 연산을 자신과 하면 결과는 0이 됩니다.


int a = 10;

a^=a

printf("%d", a);

결과 :


$ 0


XOR 연산을 0과 했을 때

XOR 연산을 0과 하면 결과는 자기자신이 됩니다.


int a = 10;

a^=0

printf("%d", a);

결과 :


$ 10


업데이트(2019.03.15) : 사례 추가 및 객체를 이용한 코드로 변경

Java List에서 for문을 사용할 때 index를 가져오는 방법을 알아보자


환경

  • Java


상황

  • for-each문을 이용해 반복문을 실행할 때 객체의 index를 알고 싶은 상황
  • 앱을 개발할 때 sqlite3를 통해서 음악 자료들을 가져와서 ArrayList에 객체로 담아두었을 때 특정 조건에 해당하는(조건문을 통해) 객체들의 Index를 가져오고 싶은 상황에서 아래 코드로 개선하였습니다.
  • 사실, for-each가 아닌 일반적인 for문을 이용하면 해당 i번째를 index로 이용하면 됩니다.
  • 다음 아래와 같은 Class가 있고 해당 Class로 객체를 만들었다고 가정
public class Test{
    String name;
    String strVal;
    int intVal;
    public Test(){

    }
    public Test(String name, String strVal, int intVal){
        this.name = name;
        this.strVal = strVal;
        this.intVal = intVal;
    }
}


(방법1) ArrayList에서 객체의 index 가져오기

index 변수를 이용

  • 반복문을 진행하기 전에 index라는 변수를 선언하고 반복문을 진행하면서 index를 증가시킵니다.

// 객체들을 담는 리스트
ArrayList<Test> arrayList = new ArrayList<Test>();
// index를 저장할 리스트(특별한 용도는 없이 본문에서는 index를 저장하기 위해 사용)
ArrayList<Integer> arrayIndexList = new ArrayList<Integer>();

// index 변수를 선언
int index = 0;
for (Test element : arrayList){
    if(element.intVal == 3){
        arrayIndexList.add(index);
    }
    // index 증가
    index++;
}


(방법2) ArrayList에서 객체의 index 가져오기

indexOf 함수를 이용

  • 특정 객체를 참조하는 변수가 있을 때 해당 변수를 사용하면 indexOf(객체변수)를 이용해서 해당 객체의 index를 자료구조 안에서 찾을 수 있습니다.
  • indexOf()함수는 자료구조에서 하나하나 객체와 비교해가면서 값을 찾기 때문에 O(n)의 복잡도를 갖게 되며 for-each를 사용할 때 객체의 index를 알고 싶다면 위에 (방법1)을 쓰는 방향이 좋다고 합니다.

// 객체들을 담는 리스트
ArrayList<Test> arrayList = new ArrayList<Test>();
// index를 저장할 리스트(특별한 용도는 없이 본문에서는 index를 저장하기 위해 사용)
ArrayList<Integer> arrayIndexList = new ArrayList<Integer>();

for (Test element : arrayList){
    if(element.intVal == 3){
        // 아래처럼 indexOf(객체) 함수를 이용
        arrayIndexList.add(arrayList.indexOf(element));
    }
}


참고자료

Short Circuit Evaluation에 대해서 간단하게 알아보자


환경

  • C, C++


Short Circuit Evaluation이란?

  • Short Circuit Evaluation이란 AND 혹은 OR의 연산에 있어서 결과가 확실하게 예측이 되었을 때 뒤에 나머지 연산을 실행하지 않고 답을 내버리는 경우를 의미합니다.


AND 연산의 경우

  • AND연산의 경우에 false가 우선 나와버리면 AND 뒤에 나오는 연산은 생략이됩니다.

OR 연산의 경우

  • OR연산의 경우에 true가 우선 나와버리면 OR 뒤에 나오는 연산은 생략이됩니다.


Short Circuit Evaluation 예제

구체적인 예시는 아래 코드와 같습니다.

AND 연산의 경우

#include <stdio.h>

int main (){
	int pass = 0;
	int i = 0;

	if(pass && i++){} //i++이 실행되지 않습니다.

	printf("pass : %d i : %d\n", pass, i);

	return 0;
}

결과는 아래와 같습니다.

$ ./and_example
$ pass : 0 i : 0


OR 연산의 경우

#include <stdio.h>

int main (){
	int pass = 1;
	int i = 0;

	if(pass || i++){} //i++이 실행되지 않습니다.

	printf("pass : %d i : %d\n", pass, i);

	return 0;
}

결과는 아래와 같습니다.

$ ./or_example
$ pass : 1 i : 0