728x90

 

 

 

#include "Calculator.h"

#include <stdio.h>

#include <stdlib.h>


char* PostfixNotation(char* str)

{

//stridx->후기표기법으로 수정 할 문자열 인덱스,idx->변환 된 문자가 들어갈 인덱스

int stridx=0,idx=0;

char PostStr[SIZE_ARR];

Stack s;

StackInit(&s);

 

while(str[stridx]>0)

{

char a=str[stridx];


if(a>='0'&&a<='9') //피연산자는 바로 PostStr에 저장

{

PostStr[idx]=a;

stridx++;

idx++;

}

else

{

switch(a) // a가 연산자일경우 : 우선순위 *,/ > +,- > ( [ ')'나오면 '('나올때까지 Pop]

{

case '+':case '-'

{

if(SIsEmpty(&s)) // 스택에 비었을 경우 바로 Push

{

SPush(&s,a);

stridx++;

}

else if(SPeek(&s)=='(') // '('있을경우 그대로 Push

{

SPush(&s,a);

stridx++;

}

else // 같은 연산자이거나, *혹은/연산자가 있을경우 전부 Pop한 후 Push

{

while(!SIsEmpty(&s))

{

PostStr[idx]=SPop(&s);

idx++;

}

SPush(&s,a);

stridx++;

}

break;

}

case '*':case '/': //우선순위가 가장 높기 때문에 그대로 Push

{

SPush(&s,a);

stridx++;

break;

}

case '(': //가장 낮은 우선순위이면서 특이한 케이스 그대로 Push

{

SPush(&s,a);

stridx++;

break;

}

case ')': //'('나올 때 까지 모두 Pop시켜줌

{

while(SPeek(&s)!='(')

{

PostStr[idx]=SPop(&s);

idx++;

}

SPop(&s);

stridx++;

break;

}

}

}

}


while(!SIsEmpty(&s))

{

PostStr[idx]=SPop(&s);

idx++;

}

return PostStr;

}


void SInit(IntStack *ps)

{

ps->TopIndex=-1;

}


int SEmpty(IntStack *ps)

{

if(ps->TopIndex==-1)

return TRUE;

else

return FALSE;

}


int SFull(IntStack *ps)

{

if(ps->TopIndex==SIZE_ARR)

return TRUE;

else

return FALSE;

}



void Push(IntStack *ps,int data)

{

ps->arr[++ps->TopIndex]=data;

}


int Pop(IntStack *ps)

{

return ps->arr[ps->TopIndex--];

}


int Peek(IntStack *ps)

{

return ps->arr[ps->TopIndex];

}



//피연산자는 스택에 바로 Push, 연산자가 나올 때마다 스택 Pop두번해 피연산자 2개 호출 후 연산 뒤 다시 스택에 Push

int CalculatePost(char* str)

{

int idx=0;

int i=0;

IntStack s;

SInit(&s);


while(str[idx]>0)

{

int num=0;


if(str[idx]>='0'&&str[idx]<='9')

{

Push(&s,(str[idx]-'0'));

idx++;

}

else

{

switch(str[idx])

{

case '+':

{

num=Pop(&s)+Pop(&s);

Push(&s,num);

idx++;

break;

}

case '-':

{

num=Pop(&s)-Pop(&s);

Push(&s,num);

idx++;

break;

}

case '*':

{

num=Pop(&s)*Pop(&s);

Push(&s,num);

idx++;

break;

}

case '/':

{

num=Pop(&s)/Pop(&s);

Push(&s,num);

idx++;

break;

}

}

}

}


return Pop(&s);

}

728x90
Posted by 정망스
,

빅오표기법 정리.

C++ 2015. 1. 7. 12:24
728x90

빅오표기법이란?

시간 복잡도를 표현하는 표기법으로써

시간 복잡도란 해당하는 알고리즘이 데이터 양에 따라서 처리하는 시간이 얼마나 걸리는지에 대한 표현이다.

 

1. O(1)

상수형 빅-오 , 데이터의 양과는 상관없이 일정한 실행 시간을 가진다

ex) 해쉬검색 알고리즘

 

2. O(log n)

로그형 빅-오, 데이터 양이 많아져도 증가율에 비해서 연산횟수의 증가율이 훨씬 낮다.

ex) divide&conquer(이진 검색, mergesort, quicksort)

 

3. O(n)

선형 빅-오, 데이터 양에 따라 시간이 정비례 한다.

ex) 선형탐색, 1중 for문

 

4. O(n*log n)

선형로그형 빅-오, 데이터양이 N배 많아지면 실행 시간은 N배 보다 조금더 많아 진다.(정비례 하지 않음)

ex) divide&conquer 이후에 다시 하나로 모으는 경우, 이진 트리 검색시 로직에 for문을 덮어 씌우는 경우

 

5. O(n²) (n의 제곱)

데이터 양에 따라 걸리는 시간은 제곱에 비례한다.

ex) 2중 for문, 삽입정렬, 선택정렬, 버블정렬

 

6. O(n³) (n의 세제곱)

데이터 양에 따라 걸리는 시간은 세제곱에 비례한다.

ex) 3중으로 중첩된 반복문

 

7. O(2ⁿ)

지수형 빅-오,  지수적 증가라는 무서운 연산횟수의 증가를 보임, 사용하는것 자체가 비현실적인 알고리즘

 

속도가 빠른 순서는 1번부터 ~ 7번 순서이다.

728x90
Posted by 정망스
,

C++ 스타일의 캐스트

C++ 2014. 12. 31. 14:46
728x90

사용법

C스타일의 캐스팅 방식 -> (타입) 표현식

C++  스타일의 캐스팅 방식 -> static_cast<타입>(표현식)

 

c++ 캐스팅을 써야 하는 이유

타이핑 면에서는 불편할수 있지만 c++ 캐스팅을 쓰게되면

가독성이 좋아지고

캐스팅 에러를 컴파일러가 대신 찾아 주기 때문에 사용해야 한다.

 

1. static_cast

기본적인 캐스트 연산자로써 struct를 int 타입으로 바꾸거나 double을 포인터 타입으로 바꾸는 이상한 타입 변환은 불가능하며 가능한 형변환만 하는 기본적인 캐스트

 

2. const_cast

상수성이나 휘발성(volatile)을 없애는데 사용하는 캐스트

 

* volatile : 도스 환경에는 인터럽트, 유닉에스는 데몬, 윈도우에는 서비스 등의 백그라운드 프로세스 등이 존재 하는데 어떠한 변수의 값을 프로세스나 스레드가 값을 실행중에 바꿔버릴수 잇는 경우도 존재한다.

그럴경우 변수 선언문 앞에 volatile를 붙이면 컴파일러는 이 변수에 대해 어떠한 최적화 처리(값이바뀌는 등)도 하지 않게 되고 개발자가 작성한 코드 그대로 컴파일하게된다. 

 

3. dynamic_cast

상속 계층 관계를 가로지르거나 하향시킨 클래스 타입으로 안전하게 캐스팅할 때 사용

(*상속 관계에 있지 않은 곳에는 사용할수 없다)

 

4. reinterpret_cast

함수 포인터 타입을 서로 바꿀때 사용한다.

하지만 이것은 왠만하면 사용하지 않는것이 좋다고 한다.

함수 포인터의 캐스팅은 소스의 이식성을 떨어뜨리고 이런 캐스팅은 잘못된 결과를 낳을수 있기 때문에 왠만하면 피해라고 한다. 

 

 

728x90
Posted by 정망스
,
728x90

이번 포스팅은 저희가 필요로 하는 클래스나, 함수등을 직접 라이브러리로 만들어서 적용시켜보겠습니다.

(2)번 포스팅에 이어서 프로젝트는 동일합니다.

 

/////////////// 사용자 정의 라이브러리 생성 및 사용법 ///////////////

 

 

1. CreateLib 솔루션 오른쪽 클릭 -> 새프로젝트 추가 -> Win32 콘솔 응용 프로그램을 만듭니다.

프로젝트 이름은 Userlib 로 만들겠습니다.

 

설정은 DLL, 내보내기 기호 체크 해주세요.

 

 

Userlib 프로젝트에서 클래스를 추가 해줍니다. 클래스는 CCalc 라는 명의 클래스를 만들도록 하겠습니다.

 

 

2. 함수를 하나 만드는데 함수는 간단 두개의 int형 매개변수를 받아서 그 차의 값을 리턴해주는 함수를 생성하겠습니다.

 

 

3. view에서 Userlib 프로젝트의 CCalc.h 헤더 파일을 include 해주고 생성자에서

CCalc 클래스에있는 sub 함수를 호출하고 있지만 참조할수 없다는 링크에러가 나옵니다.

 

 

4. 동적,정적 라이브러리를 할때와 마찬가지로 CreatLib 프로젝트 속성으로 들어가신후 공용 속성에서 새 참조 추가를 Userlib 프로젝트로 설정해 줍니다.

 

 

 

 Userlib.h 헤더 파일로 가보면

#ifdef USERLIB_EXPORTS
#define USERLIB_API __declspec(dllexport)
#else
#define USERLIB_API __declspec(dllimport)
#endif

 

이러한 코드가 있습니다. 이 코드를 복사 한후 밑의 사진처럼 CCalc.h 헤더 파일에 붙여 주시고

 

클래스 이름 앞에 USERLIB_API를 붙여 줍니다.

(win32 콘솔 에서는 이 코드가 바로 외부에서 사용 가능하게 만들어주는 기능을 한다고 합니다.)

그럼 링크 에러가 사라집니다.

 

 

5.  똑같이 Debug 폴더에 Userlib.lib와, User.dll 이라는 우리가 만든 프로젝트 이름의 라이브러리가 생성 됩니다.

 

 

 

늘 그랬듯이. CreateLib 폴더 안에 Userlib.lib를 붙여 넣어 주시고

 

 

비쥬얼 스튜디오로 돌아와서 CreateLib 프로젝트 오른쪽 클릭 -> 속성 -> 링커 -> 입력 에서

추가종속성 편집을 실행하신후 추가한 Userlib.lib 이름을 적어주시고 적용시켜 주시면

4번에서 새참조 추가를 했던 Userlib 프로젝트를 지우고 컴파일 해보셔도 이제 잘 되는 것을 확인할수 있습니다.

 

 

여기까지 사용자가 직접 정의해서 라이브러리를 생성 하고 적용 시키는 방법 이였습니다.

 

(다른 여러 방법이 더 있겠지만 저도 아직 잘 모르는 부분이 많다는점... )

728x90
Posted by 정망스
,
728x90

이번 포스팅은 동적 라이브러리를 생성하고 적용시켜보겠습니다.

(1)번 포스팅에 이어서 프로젝트는 동일합니다.

 

/////////////// 2. 동적 라이브러리 생성 및 사용법 ///////////////

 

1. CreateLib 솔루션 오른쪽 클릭 -> 새프로젝트 추가 -> MFC DLL 만듭니다.

프로젝트 이름은 mfcdll 로 만들겠습니다.

 

설정은 MFC 확장 DLL에 체크 해주세요.

 

 

2. 테스트를 위해서 리소스 뷰에서 mfcdll 프로젝트에 다이얼로그를 하나 생성 하겠습니다.

ID 값은 IDD_TEST_DLL로 설정했습니다.

 

 

다이얼로그를 더블클릭 하시면 클래스 추가 마법사 창이 뜹니다.

이름은 CTestDialog 로 하고 클래스를 하나 생성하겠습니다.

 

추가 하신후 IDD_TEST_DLL 이 정의되지 않았습니다. 와 같은 오류가 뜨면

resource.h 헤더를 include 해주시면 해결 됩니다.

 

 

3. view 화면으로 돌아와서 mfcdll 프로젝트에 있는 TestDialog.h 헤더 파일을 include 해주고

생성자 에서 앞서 만들엇던 다이얼로그 창을 띄우는 코드를 넣고 컴파일 해보면

정적 라이브러리 생성때와 같이 링크 에러가 발생합니다.

 

 

4. 정적 라이브러리 때와 마찬가지로 CreatLib 프로젝트 속성으로 들어가신후 공용 속성에서 새 참조 추가를 mfcdll 프로젝트로 설정해 줍니다.

 

 

 

그리고 TestDialog.h 헤더 파일에서 class 이름 앞에 AFX_EXT_CLASS 라는 키워드를 붙여줍니다.

이 키워드는 외부에서도 이 클래스에 접근 가능하게하여 사용할수 있게 해준다는 키워드입니다.

(mfc일경우에 한해서 사용하는 키워드)

 

다 하셨으면 이제 문제없이 컴파일이 잘 되는것을 확인 하실수 있습니다.

 

 

5. 정적때와 마찬가지로 여기까지 잘 따라하시면서 컴파일 하셧다면 프로젝트 명과 동일한 mfcdll.dll 와 mfcdll.lib 2개가 생성된것을 보실수 있습니다.

 

동적 라이브러리 같은 경우에는 dll와, lib 2개가 생성됩니다.

 

 

6. CreateLib 폴더에 mfcdll.dll와, mfcdll.lib 라이브러리를 추가해 줍니다.

 

 

비쥬얼 스튜디오로 돌아와서 CreateLib 프로젝트 오른쪽 클릭 -> 속성 -> 링커 -> 입력 에서

추가종속성 편집을 실행하신후 추가한 mfcdll.lib 이름을 적어주시고 적용시켜 주시면

새참조 추가를 했던 mfcdll 프로젝트를 지우고 컴파일 해보셔도 이제 잘 되는 것을 확인할수 있습니다.

 

 

추가는 lib만 하는데 dll은 왜 같이 넣는지 처음에 제가 궁금했었고 보시는분들도 궁금하실수 있는데

dll은 추가하는것이 아니고 dll을 같이 넣지 않으면 원래 이 라이브러리는 dll을 기준으로 만들어 졌기 때문에

컴파일이나, 빌드 하는데 있어선 문제가 없지만 프로그램 실행을 하는데 있어서 dll이 같이 없다면 해당하는 dll이 없어서 실행을 못한다 라는 오류가 뜨게 된다고 합니다.

 

아무튼 여기까지 동적 라이브러리 생성 하고 적용하여서 실행하면 우리가 만든 다이얼로그가 뜨는것을 알수 있습니다. 라이브러리가 재대로 추가되서 사용 되고 있다는 뜻입니다!

 

다음엔 우리가 직접 만들거나, 혹은 필요한 클래스나 함수등등을 라이브러로 만들어서 사용하는 방법을 포스팅 해보겠습니다.

728x90
Posted by 정망스
,


맨 위로
홈으로 ▲위로 ▼아래로 ♥댓글쓰기 새로고침