study2015. 4. 2. 11:41

Visual Studio를 사용해서 알고리즘 연습혹은 구현하다 보면 TC (Test Case)의 데이터를 파일로 부터 읽어올 일이 생긴다.

예를 들면 아래코드에서 주석 처리된 부분, input.txt를 freopen을 이용해서 stdin으로 출력 할 수 있지만,

Visual Studio Project properties에 Command line을 설정해서 간단하게 처리 할 수 있다.

#include <stdio.h>


int main(void)

{

int T;

int N, K;


  //freopen("input.txt", "r", stdin);

setbuf(stdout, NULL);

scanf("%d", &T);


for (int tcIdx = 1; tcIdx <= T; ++tcIdx)

{

scanf("%d\n", &N);

scanf("%d\n", &K);

printf("%d, %d, %d\n", tcIdx, N, K);

}


return 0;

}


Visual Studio Menu -> Project -> (your project name) Properties... -> Configuration Properties -> Debugging -> Command Arguments 를 보면 텍스트 필드가 있는데 아래처럼 적는다.

< input.txt


만약 Console에 출력되는 값을 파일로 저장하고 싶다면? 이때도 Command Arguments 을 이용하면 된다.


< input.txt > output.txt

이렇게 하면 입력은 input.txt로 출력은 output.txt로 한다.


++ 추가 

setbuf를 썼는데 빌드 할 때 아래와 같은 에러가 발생하면.

error C4996: 'setbuf': This function or variable may be unsafe. Consider using setvbuf instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.


Visual Studio Menu -> Project -> (your project name) Properties... -> Configuration Properties -> C/C++ ->Preprocessor -> Preprocessor Definitions 에 _CRT_SECURE_NO_WARNINGS을 추가 해주자.


Visual Studio Menu -> Project -> (your project name) Properties... -> Configuration Properties -> Linker -> System -> SubSystem 을

Console (/SUBSYSTEM:CONSOLE) 으로 하면 프로그램 실행 이후에도 콘솔창이 사라지지 않는다.






Posted by 평면우주
study2015. 1. 29. 15:41

카운팅 소트 설명.

http://en.wikipedia.org/wiki/Counting_sort 

역시 C언어로 간단하게 구현해 보았다.


//# counting sort.

#include <stdio.h>


#define MAXLEN 10


void main()

{

int Data[MAXLEN] = {8, 1, 3, 2, 9, 9, 7, 10, 5, 2}; // item is 1 <= N <= 10

int ret[MAXLEN] = { 0, };

int count[MAXLEN];

int idx = 0;


//init count index

for (int i = 0; i <= MAXLEN; i++)

count[i] = 0;


for (int i = 0; i < MAXLEN; i++)

{

count[Data[i]] += 1;

}

idx = MAXLEN - 1;

for (int i = MAXLEN; i > 0; i--)

{

while (count[i] > 0)

{

ret[idx--] = i;

count[i] -= 1;

}

}


printf("{");

for (int i = 0; i < MAXLEN; i++)

{

printf("%d,", ret[i]);

}

printf("}\n");

}





Posted by 평면우주
study2015. 1. 29. 11:05

문자열 검색 알고리즘 간단히 설명하면 문자열을 검색할 때 앞에서 부터 하는게 아니라 뒤에서 부터 시작하는 알고리즘이다.

비교를 하다가 문자가 다르다는 것을 알았다면, 그 문자가 검색키 문자열에 포함되어 있다면 그 만큼 이동함.

그 문자가 포함되어 있지 않다면 검색키 문자열 길이만큼 점프.

자세한건 아래 참고.

http://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm

간단하게 C언어로 구현해 보았다.

#include <stdio.h>


#define MAXLEN 1000


int mystrlen(char *m)

{

int n = 0;

while (*m != '\0') {

*m++;

n++;

}

return n;

}


bool compareString(char s[], char k[], int idx, int keyLen, int* jumpIdx)

{

int last = keyLen-1;

bool matchFlag = true;


for (int i = (idx + last); i >= 0; i--)

{

//printf("s[%d]=(%c), key[%d]=(%c)\n", i, s[i], last, k[last]);


if (s[i] == k[last])

{

if (last == 0)

{

*jumpIdx = keyLen;

return true;

}

}

else {

for (int j = last-1; j >=0; j--)

{

if (k[j] == s[i])

{

*jumpIdx = keyLen-j-1;

return false;

}

}


*jumpIdx = keyLen;

return false;

}


last--;

}

return false;

}


void main()

{

char source[MAXLEN] = "tomato dog cat radio good";

char key[10] = "cat";

int keyLen = mystrlen(key);

for (int i = 0; source[i] != '\0';)

{

int jump = 0;


//printf("\n==>\n");

//for (int j = 0; j < keyLen && source[i + j] != '\0'; j++)

//{

// printf("%c", source[i + j]);

//}


//printf("\n");

//for (int j = 0; j < keyLen ; j++)

//{

// printf("%c", key[j]);

//}


//printf("\n==<\n");


bool a = compareString(source, key, i, keyLen, &jump);

if (a)

printf("match");


i += jump;

}

printf("n=%d", mystrlen(key));


printf("\n");

}





Posted by 평면우주
study2015. 1. 9. 15:39

#include <stdio.h>
#define MAX_LEN 10

void swap(int*a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}

int partition(int d[], int l, int r) //l is left, r is right.
{

int first = l;
int pivot = d[first];
++l; //shift.

while (l < r)

{
while (d[l] <= pivot)
++l;
while (d[r] > pivot)
--r;

if (l < r)
swap(&d[r], &d[l]);
else
break;
}

swap(&d[first], &d[r]);
return r;
}


int partition2(int d[], int l, int r) // p is pivot index.

{

int last = d[r];
int sortIdx = l;

for (int i = l; i <= r-1; i++)

{

if (d[i] <= last)
{
swap(&d[i], &d[sortIdx]);
sortIdx++;
}
}

swap(&d[sortIdx], &d[r]);
return sortIdx;

}

void qsort(int d[], int l, int r)

{
printf("l=%d, r=%d\n", l, r);

if (r > l){
//int idx = partition(d, l, r);
int idx = partition2(d, l, r);
qsort(d, l, idx - 1);
qsort(d, idx + 1, r);
}
}


int main()

{

int i = 1;

int j = 2;

int data[MAX_LEN] = { 3, 7, 8, 5, 2, 1, 9, 5, 4, 6};
qsort(data, 0, MAX_LEN-1);

for (int k = 0; k < MAX_LEN; k++)
     {
    printf("%d,", data[k]);

}

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

}


분할 정복 알고리즘의 대표적인 소팅 알고리즘 partition 값을 구하는 방법은 전통적인 알고리즘 버젼과 MIT에서 제안한 방법 2가지 모두 구현해 보았다.

Posted by 평면우주
study2012. 6. 26. 15:24

구글맵에서는 전세계의 고도 데이터를 API로 제공한다. Google Elevation API를 이용하면 위도 경도만 알고 있으면 그 지점의 고도를 알 수 있다.


여기서는 남산 팔각정의 고도를 알아보겠다.

우선 구글맵을 이용해 원하는 지점의 위도 경도를 구한다. [  구글맵에서 위도 경도 구하기   http://milkelf.tistory.com/71 ]

남산 팔각정의 위도 경도는 (37.55157798469981, 126.98770523071289)


아래 URL 처럼 위도 경도를 채워서 요청을 하면. 고도 정보를 JSON 형식으로 리턴해준다.

(http://maps.googleapis.com/maps/api/elevation/json?locations=[위도],[경도]&sensor=false)


남산 팔각정의 고도 정보 요청

http://maps.googleapis.com/maps/api/elevation/json?locations=37.55157798469981,126.98770523071289&sensor=false


결과

{
   "results" : [
      {
         "elevation" : 258.1230468750,
         "location" : {
            "lat" : 37.55157798469981,
            "lng" : 126.9877052307129
         },
         "resolution" : 152.7032318115234
      }
   ],
   "status" : "OK"
}

여기서는 258미터로 나온다. 구글맵은 WGS84 좌표계를 쓰기 때문에 이는 해발고도(표고)라 생각하면 된다. 

실제 GPS로 측정했더니 270미터 정도가 나오는데, GPS 고도계의 오차가 20~30m 이기 때문에 오차범위에 해당한다.


조금 더 자세한 정보는 아래를 참고하세요. ~

출처 https://developers.google.com/maps/documentation/elevation/?hl=ko

Posted by 평면우주
study2012. 4. 23. 17:18

질문을 하나 받았다. Python/C API 관련 질문인데 이게 조금 복잡하다.

 

C/C++에서 파이썬을 사용하고 싶으면 Python/C API 사용해 파이썬을 프로그램에 포함시키면 된다. 아래 예제에서


#include "Python.h"


int

main(int argc, char *argv[])

{

   Py_Initialize();

 

   PyRun_SimpleString("from time import time,ctime\n"

                              "print('Today is', ctime(time()))\n");

   Py_Finalize();

}

 

현재 시간을 가져오는 프로그램을 파이썬의 time 모듈을 이용해서 구현한 것이다.

Python/C API 상위 레이어 함수인 PyRun_simpleString 사용해 쉽게 파이썬을 C/C++에서 실행 시킬 있다.

 

그렇다면 PyRun_SimpleString 번째 인수인 파이썬 구문에서 C/C++ 함수를 호출 있을 ? 물론 가능하다. 이를 위해서 파이썬 확장 모듈이라는 것이 있다.

 

파이썬에서 사용할 모듈 -여기서는 spam- 만들고 컴파일 하면 shared library 만들어 지고 이를 파이썬이 설치되어 있는 디렉터리에 옮겨 놓으면 된다.

 

그리고 아래와 같이 사용하면 된다.


PyRun_SimpleString("import spam\n"

                          "print('String Length is : ', spam.strlen('abc'))\n");

 

하지만 so 매번 옮겨 놓을 수도 없는 노릇이고, 원하는 것은 소스코드 안에서 파이썬과 C/C++ 서로 통신하듯이 쓰는 것이기 때문에   방법은 문제가 있다.

 

일단 C/C++ 함수를 파이썬에서 사용하게 하려면 함수들을 파이썬 확장 모듈로 만들어야 한다.

여기까지는 순조로웠는데, 만든 모듈을 파이썬에서 임포트 없었다.

문제는 PyRun_SimpleString안의 파이썬구문이 실행 , 우리가 만든 spam 모듈이 파이썬 built-in 네임스페이스에 포함 되지 않는 다는 것이다.

 

참고할 예제도 없어서, 주말 내내 Python Document 읽어보았다.

 

그래서 찾아낸 함수가 PyImport_ExtendInittab, PyImport_AppendInittab이다.

(http://docs.python.org/py3k/c-api/import.html?highlight=pyimport_#PyImport_ExtendInittab)

해당 모듈을 build-in 추가 해주는 고마운 함수이다. Importing Modules(http://docs.python.org/py3k/c-api/import.html) 보면 모듈을 C API에서 임포팅 하는 함수들이 나온다. PyImport_AppendInittab으로 예제를 만들고 테스트 해봤다.

 


#include "Python.h"

 

static PyObject *

spam_strlen(PyObject *self, PyObject *args)

{

    const char* str=NULL;

    int len;

 

    if (!PyArg_ParseTuple(args, "s", &str))

         return NULL;

 

    printf("argument = %s\n", str);

    len = strlen(str);

 

    return Py_BuildValue("i", len);

}

 

static PyMethodDef SpamMethods[] = {

{"strlen", spam_strlen, METH_VARARGS,

 "count a string length."},

 {NULL, NULL, 0, NULL}

};

 

static struct PyModuleDef spammodule = {

    PyModuleDef_HEAD_INIT,

    "spam",           

    "It is test module.",

    -1, SpamMethods

};

 

static PyObject* PyInit_spam(void)

{

    return PyModule_Create(&spammodule);

}

 

int

main(int argc, char *argv[])

{

 

   PyImport_AppendInittab("spam", &PyInit_spam);

 

   Py_Initialize();

 

   PyRun_SimpleString( "import spam\n"

       "print('String Length is : ', spam.strlen('abc'))\n"

   );

  

   Py_Finalize();

   return 0;

}

 


 

PyImport_AppendInittab에서 built-in 포함될 모듈의 이름과 만든 모듈 포인터를 넣어준다.

한가지 특이한 점이 PyInit_spam처럼 모듈을 바로 입력 받지 않고 함수 포인터를 받는 다는 것이다.

PyImport_AppendInittab는 Py_Initialize() 호출하기 전에 호출 되야 한다.

 

PyRun_SimpleString안의 파이썬 구문에서 spam 모듈이 정상적으로 임포트되고, 함수도 호출 되는 것을 있다.

  

 

Tip.

테스트는 리눅스에서 파이썬 3.1에서 진행했다. 파일을 컴파일 , 파이썬의 헤더 라이브러리 파일이 필요한데 아래처럼 간단하게 구할 있다.

 

cflags, ldflags 알아내는

$ /opt/bin/python3.2-config --cflags

$ /opt/bin/python3.2-config --ldflags

Posted by 평면우주
study2011. 12. 20. 13:25

처음 들어본 이름의 tool도 많이 있네요. ㅠ.ㅠ

자세한 내용은 아래 URL 참고.

http://isao76.egloos.com/2252874


Posted by 평면우주
study2011. 8. 1. 16:05
파이썬에서 시스템 명령어를 실행 시키는 방법은 여러가지가 있다.
os.system 혹은 os 의 exec 함수들을 이용하는 것이 가장 일반적이다.

하지만 간혹 시스템 명령어를 실행 시키고 그 결과값 (status)와 결과물 (output)을 가져오고 싶은 경우가 생긴다.
예를 들면
'ls'를 실행 시켰을 때. ls가 정상적으로 실행되었는지를 알아내거나, ls의 결과물을 가공한다거나 할 때 유용하게 쓸 수 있는 유틸리티가 있다.

Python 2.X 버젼에서는 commands, Python 3.X에서는 subprocess가 그것이다.

>>>#python 2.x에서...
>>>import commands
>>>commands.getstatusoutput('ls /bin/ls')
(0, '/bin/ls')     # 튜플 형태로 status와 optput을 넘겨 준다.


>>>#python 3.X
>>> import subprocess
>>>retcode = subprocess.call(["ls", "-l"])
Posted by 평면우주
study2011. 7. 30. 16:50
Python 3에서 Beautiful soup을 바로 사용할 수가 없는데 python 2에서 python 3으로 넘어오면서 문법이 많이 변경 되었기 때문이다.
그래서 Beautiful soup을 사용하기 위해선 python 3 문법으로 변경을 해 줘야 한다.

pytohn 3에서는 2to3.py 라는 스크립트를 제공한다. 2.X용 코드를 3.X로 바꿔준다.
단. 2to3가 만능은 아니다. 2to3에서 변환을 못하는 부분은 직접 변경 해줘야 한다.

다행이도 Beautiful soup 3.1 이후 버젼 부터는 2to3로 자동으로 변경되게 수정을 했다고 한다.
우선 Beautiful soup 코드를 다운 받고 다음 명령어를 수행한다.

D:\project\test>c:\Python32\python.exe c:\Python32\Tools\Scripts\2to3.py -w BeautifulSoup.py

-w옵션을 꼭 써줘야 하는데 -w를 쓰지 않으면 수정할 부분만 화면에 출력되고 정작 파일은 변경되지 않는다.

python 3용으로 변경한 Beautiful soup 3.1 버젼을 첨부파일에 추가했다.
Posted by 평면우주
study2011. 7. 18. 18:11

구글맵에서 원하는 위치에서 브라우저의 주소창에 다음과 같이 입력한다.

javascript:void (prompt('', gApplication.getMap().getCenter()));



코드를 분석 해 보면.
일단 gApplication이 눈에 띄는데 이는 구글 Web Application의 Object를 가리킨다.
getMap()은 현재 맵의 object를 가져오게 하고.
getCenter()는 맵의 center를 가져온다. (경도 위도)

모두 예상하셨겠지만. 지도의 가운데의 경도, 위도 뿐만 아니라. size 및 zoom 값도 가져올 수 있다.

javascript:void (prompt('', gApplication.getMap().getSize()));
javascript:void (prompt('', gApplication.getMap().getZoom()));



이외예도 여러가지 API를 지원하는데 자세한 사항은 아래 URL을 참고

http://code.google.com/intl/ko-KR/apis/maps/
Posted by 평면우주