파스칼의 삼각형이란 아래 사진과 같이 이항계수를 삼각형 모양의 기하학적 형태로 배열한 모양을 듯합니다.


a_{n1} = 1
a_{nn} = 1
a_{nk} = a_{{n-1}{k-1}} + a_{{n-1}{k}} (n, k>=0)

구하는 점화식은 위와 같이 나타냅니다. 이런식으로 점화식을 구하여 부분 문제를 풀어가며 전체 문제의 해답을 찾아내는 방식을 dp라고 하죠 ㅎㅎ 

아래는 n을 입력하면 처음부터 n번째 줄 까지의 파스칼의 삼각형을 구하는 예제 소스입니다


/* 파스칼의 삼각형 구하는 예제(dp) */

#include <iostream>

using namespace std;

 

int arr[100][100] = {0, };

 

int main(){

        int n;

        cin >> n;

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

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

                       if(i == 0 || j == 0){

                              arr[i][j] = 1;

                       }

                       else{

                              arr[i][j] = arr[i-1][j] + arr[i-1][j-1];

                       }

               }

        }

 

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

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

                       cout << arr[i][j] << " ";

               }

               cout << endl;

        }

 

        return 0;

}

신고

오랜만에 포스팅이네요...-_-

앞으로는 글 열심히 써야겠습니다 ㅠㅠ

최근에 Nginx에 보안인증서를 달아야 하는 일이 있었는데 한참을 고생했네요...

이 글을 통해서 저와 같은 멘붕을 겪는 분들이 없길 바래요


1. CSR(Certificate Signing Request) 생성

CSR 이란 SSL을 사용하기 위해서 SSL을 제공하는 회사에게 SSL을 사용하고 싶다고 신청하는 일종의 신청서라고 생각하시면 될 것 같습니다. 신청서니까 여러가지 입력 양식이 있겠죠??

우선 openssl이 설치되어 있어야 합니다.

openssl 설치 명령어
sudo apt-get install libssl-dev openssl

openssl을 설치했다면 다음 명령어로 CSR 파일을 만들어봅시다.
참고로 저는 /etc/nginx/ssl 디렉토리에서 작업했습니다

root@www:/etc/nginx/ssl# openssl req -nodes -newkey rsa:2048 -keyout myserver.key -out server.csr

위와 같이 명령어를 입력하면 

CSR 파일 생성을 위한 여러가지 입력 폼이 뜨게 됩니다.

Country Name ( 국가코드) [] : KR
State or Province Name ( 지역 ) [] : Seoul
Locality Name ( 시/군/구 ) [] : Seocho
Organization Name ( 회사명 ) [] : 회사명 Inc
Organizational Unit Name ( 부서명 ) [] : Develop Team
Common Name ( 서비스도메인명 ) [] : www.domain.com
Email Address [] : 현재 도메인 소유자의 이메일 주소


입력 양식은 위 양식을 참고해서 입력해주시면 될 것 같습니다. 입력을 다 하면 myserver.key 파일과 server.csr 파일이 생성이 됩니다. cat 명령어로 csr 파일을 보면

형태로 저장이 되있는 것을 확인 할 수 있습니다. 

2. 만들어진 CSR을 업체에 요청하여 SSL 인증서 받아오기

위의 텍스트를 직접 AlphaSSL 공식 사이트(https://www.alphassl.com/)나 SSL 신청 대행업체(가비아 등)에 요청을 합니다. 저는 가비아를 이용해서 대행신청을 했구요. 

신청을 완료하면 신청자 메일로 AlphaSSL 인증서 발급 알림 메일이 날라옵니다.

3. PEM 파일 만들기

메일로 받은 인증서 말고 2개의 파일을 더 추가해야 합니다.

1. 먼저 https://www.alphassl.com/support/roots/root.txt 를 들어가서 root ca의 텍스트 값을 저장합니다.

2. https://www.alphassl.com/support/install-root-certificate.html 를 들어가서 AlphaSSL Intermediate CA의 텍스트 값을 저장해야합니다. 여러가지 종류가 나오는데 거기에서 구매한 SSL에 맞춰서 복사를 하시면 됩니다. 저는 일반 상품을 구매하였기 때문에 아래에 있는 Intermediate CA를 저장했습니다.

그리고 pem 파일을 생성해야 합니다. pem 파일은

-----BEGIN CERTIFICATE-----

메일을 통해 받은 인증서 텍스트 값

-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----

ROOT CA 텍스트 값

-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----

Intermediate CA 텍스트 값

-----END CERTIFICATE-----

과 같은 방식으로 만들어 주시면 됩니다(순서 꼭 지켜야 합니다! 하나라도 빠지면 안됩니다)

실질적으로 필요한 파일은 초기에 CSR을 만들면서 같이 생성된 key 파일과 방금 설명한 pem 파일입니다. 저는 이 파일을 myDomain.pem로 저장하였습니다.

그리고 SSL을 설정할 사이트의 conf 파일에

server {

  listen 443;

  ssl on; 

  ssl_certificate /etc/nginx/myDomain.pem; // pem 파일이 저장된 디렉토리 설정

  ssl_certificate_key /etc/ssl/private/myserver.key; // 키 파일이 저장된 디렉토리


  // 나머지 부분은 80번 포트 기본 설정 그대로  

}

이 부분을 추가하고 nginx를 restart 하시면 올바르게 적용이 되는 것을 확인하실 수 있습니다!

신고

'Linux' 카테고리의 다른 글

Nginx기반 SSL 보안인증서 설치 방법(AlphaSSL)  (1) 2015.05.07
  1. hello2017 2016.04.04 15:20 신고

    발급시 https://www.securesign.kr/ 여기도 참고해 보시면 어떨까 합니다~

INCOGNITO 2014 HACKING CONFERENCE
08.18(Mon) - 0820(Wed) 송파구 올림픽 파크텔

http://inc0gnito.com/
인코그니토 홈페이지가 2014년도에 맞추어 리뉴얼 되었습니다.



신고

'etc > essay' 카테고리의 다른 글

제3회 인코그니토 컨퍼런스  (0) 2014.08.05
ㅎㅎ  (0) 2013.10.12
  (0) 2013.09.18
제2회 청소년 화이트해커 경진대회 개최 안내  (0) 2013.05.06
SW Maestro 미국 단기해외연수를 마치고...  (0) 2013.01.15
벌써 절반이 지나고...  (0) 2012.10.29
이력서는 언제쓰지...?ㅋㅋ


신고

'etc > essay' 카테고리의 다른 글

제3회 인코그니토 컨퍼런스  (0) 2014.08.05
ㅎㅎ  (0) 2013.10.12
  (0) 2013.09.18
제2회 청소년 화이트해커 경진대회 개최 안내  (0) 2013.05.06
SW Maestro 미국 단기해외연수를 마치고...  (0) 2013.01.15
벌써 절반이 지나고...  (0) 2012.10.29

여기 존재를 잊고있었다니...ㅋㅋㅋ


신고

'etc > essay' 카테고리의 다른 글

제3회 인코그니토 컨퍼런스  (0) 2014.08.05
ㅎㅎ  (0) 2013.10.12
  (0) 2013.09.18
제2회 청소년 화이트해커 경진대회 개최 안내  (0) 2013.05.06
SW Maestro 미국 단기해외연수를 마치고...  (0) 2013.01.15
벌써 절반이 지나고...  (0) 2012.10.29

<인하대학교 공식대회>
일시 : 2013. 5. 17 오후 10:00 ~ 2013. 5. 19 오전 10:00 (총 36시간)
주최 : 인하대학교
주관 : 인하대학교 컴퓨터정보공학부
운영 : 인하대학교 컴퓨터클럽 뉴하트 (NewHeart)
대회 사이트 : http://play.newheart.kr/






신고

'etc > essay' 카테고리의 다른 글

ㅎㅎ  (0) 2013.10.12
  (0) 2013.09.18
제2회 청소년 화이트해커 경진대회 개최 안내  (0) 2013.05.06
SW Maestro 미국 단기해외연수를 마치고...  (0) 2013.01.15
벌써 절반이 지나고...  (0) 2012.10.29
공업수학 ch1&ch2  (0) 2012.10.11

메서드 재정의(virtual, override)


virtual

부모 클래스 함수 앞에 붙는 연산자.

자식 클래스에 의해서 재정의될 수 있다는 의미를 가지고 있다.

컴파일러는 이 지정자가 붙은 함수를 비가상함수와 다르게 컴파일함으로써 재정의될 준비를 한다.


override

자식 클래스 함수 앞에 붙는 연산자.

부모로부터 상속받은 함수와는 다르게 구현한다는 의미를 가지고 있다.

재정의되는 함수는 부모의 함수와 이름, 시그니처도 일치해야함.

재정의된 함수는 부모의 함수에 의존적인 경우가 많은데 이 때 base 키워드로 부모의 원래함수를 호출 할 수 있다.


예제

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

 

class Base

{

    public virtual void echo()

    {

        Console.WriteLine("base echo~!!");

    }

}

 

class Derived : Base

{

    public override void echo()

    {

        Console.WriteLine("derived echo~!!");

    }

}

 

class Program

{

    static void Main()

    {

        Base B = new Base();

        Derived D = new Derived();

        B.echo();

        D.echo();

        Base B2 = D;

        B2.echo();

    }

}

 

실행결과



B.echo와 D.echo는 당연한 결과라고 볼 수 있지만 B2.echo호출문의 결과는

derived echo~!!라는 결과를 출력합니다. 


                                                       Base B2 = D;

위 선언에서 B2의 정적 타입은 Base

B2의 동적 타입은 Derived가 됩니다.


일반적인 비가상 메서드는 정적 타입을 따르지만 가상 메서드에서는 

호출 객체가 실제로 가리키고 있는 타입, 즉 동적 타입을 따르게 됩니다.


echo함수가 가상함수 일 때에는 B2가 비록 Base타입이지만 Derived객체를 가리키고 있기 때문에

Derived의 메서드가 호출이 됩니다.


그렇다면 위 예제를 비가상 함수로 바꾸어 출력을 해보도록 하겠습니다.


public virtual void echo()

이 부분에서 virtual을 빼고,

public override void echo()

이 부분에서 override는 new로 바꾸어 출력해보겠습니다.



실행결과




참고.

여기서 new를 안붙이고 public void echo()로 변환해도 결과는 같습니다.

new를 붙이는 이유는 상속받은 멤버를 완전히 숨겨버리고 자식 클래스가 같은 이름으로 새로운 멤버를 만든다는 뜻으로써, 의도적으로 같은 이름을 사용한다는 것을 알리는 연산자라고 볼 수 있습니다.

물론 멤버를 숨기는 것이지 상속을 안받는다는 뜻은 아닙니다.

base.메서드명()을 이용하면 부모의 숨겨진 멤버를 상속 받을 수 있게 됩니다.

신고

'Windows Programming > Windows::C#' 카테고리의 다른 글

[C#] 메서드 재정의(virtual, override)  (0) 2013.03.31
[C#] 상속 예제  (0) 2013.03.31
C# GUI 구구단 프로그램  (0) 2012.02.16
윈도우즈 폼 예제  (0) 2012.02.16
C# 콘솔 예제(성적관리 프로그램)  (0) 2012.02.16

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

 

class Human

{

    protected string Name;

    protected int Age;

    public Human(string aName, int aAge)

    {

        Name = aName;

        Age = aAge;

    }

    public virtual void Intro()

    {

        Console.WriteLine("Name : " + Name);

        Console.WriteLine("Age : " + Age);

    }

}

 

class Student : Human

{

    protected int StNum;

    public Student(string aName, int aAge, int aStNum) : base(aName, aAge)

    {

        StNum = aStNum;

    }

    public override void Intro()

    {

        base.Intro();

        Console.WriteLine("stuNumber : " + StNum);

    }

    public void Study()

    {

        Console.WriteLine("study");

    }

}

 

class Program

{

    static void Main()

    {

        Student Kim;

        Kim = new Student("Minhwa Jin", 25, 921223);

        Kim.Intro();

        Kim.Study();

    }

}

 

base(aName, aAge)

부모의 생성자를 호출하여 초기화하는 구문입니다.

기존의 StNum은 직접 자신의 생성자에서 초기화를 하게 되구요.


여기서 base를 주석처리를 하게 되면 기반 클래스(부모)의 디폴트 생성자가 호출되는데요.

Human에서는 디폴트 생성자가 없기 때문에 에러가 납니다.


이름과 나이를 출력하는 코드가 기반 클래스(부모)에 작성되어있기 때문에

Intro를 호출하면 출력이 되겠지요~


그리고 기본적으로 c#상속은 public 상속만 지원하며, 다중 상속을 지원하지 않고

상속없이 단독 클래스를 정의하는 것도 허용되지 않는다고 합니다~


실행결과





아 참고로 제나이 22 입니다...-_-;


신고

'Windows Programming > Windows::C#' 카테고리의 다른 글

[C#] 메서드 재정의(virtual, override)  (0) 2013.03.31
[C#] 상속 예제  (0) 2013.03.31
C# GUI 구구단 프로그램  (0) 2012.02.16
윈도우즈 폼 예제  (0) 2012.02.16
C# 콘솔 예제(성적관리 프로그램)  (0) 2012.02.16

클라이언트에서 피연산자 2개와 연산자 1개를 입력받으면 서버에서 연산을 하여 다시 클라이언트에게 결과값을 보여주는 프로그램을 만들어보았습니다.(리눅스 환경)


/* server */


#include <unistd.h>

#include <stdlib.h>

#include <string.h>

#include <sys/stat.h>

#include <sys/socket.h>

#include <netinet/in.h>

#include <arpa/inet.h>

#include <sys/time.h>


#define PORT 3600


struct cal_data{ // 주고받을 데이터 구조체 정의

int left_num;

int right_num;

char op;

int result;

short int error;

};


int main(int argc, char **argv)

{

struct sockaddr_in client_addr, sock_addr;

int listen_sockfd, client_sockfd;

int addr_len;

struct cal_data rdata;

int left_num, right_num;

short int cal_result;


if((listen_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)

{

perror("error");

return 1;

}

memset((void *)&sock_addr, 0x00, sizeof(sock_addr));

sock_addr.sin_family = AF_INET;

sock_addr.sin_addr.s_addr = htonl(INADDR_ANY);

sock_addr.sin_port = htons(PORT);

if(bind(listen_sockfd, (struct sockaddr *)&sock_addr, sizeof(sock_addr)) == -1)

{

perror("error");

return 1;

}

if(listen(listen_sockfd, 5) == -1)

{

perror("error");

return 1;

}

while(1)

{

addr_len = sizeof(client_addr);

client_sockfd = accept(listen_sockfd, (struct sockaddr *)&client_addr, &addr_len);

if(client_sockfd == -1)

{

perror("error");

return 1;

}

read(client_sockfd, (void *)&rdata, sizeof(rdata)); // 소켓에서 데이터를 읽어옴

rdata.error = 0;

left_num = ntohl(rdata.left_num); // 네트워크 바이트 순서 변환

right_num = htonl(rdata.right_num);

switch(rdata.op) // 연산 수행

{

case '+':

cal_result = left_num + right_num;

break;

case '-':

cal_result = left_num - right_num;

break;

case '*':

cal_result = left_num * right_num;

break;

case '/':

if(right_num == 0)

{

rdata.error = 2;

break;

}

cal_result = left_num / right_num;

break;

default:

rdata.error = 1;

}

rdata.result = htonl(cal_result); // 결과 값을 네트워크 바이트 순서에 맞춤.

rdata.error = htons(rdata.error);

write(client_sockfd, (void *)&rdata, sizeof(rdata)); // 전송~

close(client_sockfd);

}

close(listen_sockfd);

return 0;

}



/* client */

#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/time.h>
#include <stdio.h>

#define PORT 3600
#define IP '127.0.0.1'

struct cal_data{
int left_num;
int right_num;
char op;
int result;
short int error;
};

int main(int argc, char **argv)
{
struct sockaddr_in serveraddr;
int server_sockfd;
int client_len;
char buffer[256];
int len;
struct cal_data sdata;

len = sizeof(sdata);
memset(&sdata, 0x00, len); // 구조체를 초기화
sdata.left_num = atoi(argv[1]); // 구조체에 인자로 입력받은 값을 채운다.
sdata.right_num = atoi(argv[2]);
sdata.op = argv[3][0];

if((server_sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
perror("error");
return 1;
}
serveraddr.sin_family = AF_INET;
serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
serveraddr.sin_port = htons(3600);
client_len = sizeof(serveraddr);
if(connect(server_sockfd, (struct sockaddr *)&serveraddr, client_len) == -1)
{
perror("connect error");
return 1;
}
sdata.left_num = htonl(sdata.left_num);
sdata.right_num = htonl(sdata.right_num);
if(send(server_sockfd, (void *)&sdata, len, 0) <= 0) // 구조체 서버 전송
{
perror("write error");
return 1;
}
if(recv(server_sockfd, (void *)&sdata, len, 0) <= 0) // 결과값 읽어옴.
{
perror("read error");
return 1;
}
printf("%d %c %d = %d\n", ntohl(sdata.left_num), sdata.op, ntohl(sdata.right_num), ntohl(sdata.result));
close(server_sockfd);
return 0;
}


먼저 cal_server를 켠 뒤 cal_client를 argv인자로 입력받아 실행시키면 결과값이 출력되는 것을 보실 수 있습니다.


cal_client.c


cal_server.c



신고

'Linux > Linux Programming' 카테고리의 다른 글

[TCP/IP] 온라인 사칙연산 서비스 구현  (0) 2013.02.09
Linux TCP/IP 소켓 프로그래밍  (0) 2013.01.27
Linux Shell 구현  (0) 2013.01.27

#include <iostream>

 

using namespace std;

 

class Node{ // Node Class

public:

        Node(int n);

        Node* nextNode;

        Node* prevNode;

        int data;

};

 

Node::Node(int n)

{

        data = n;

        nextNode = NULL;

        prevNode = NULL;

}

 

class Queue{ // Queue

public:

        Queue();

        void enQueue(int n);

        void deQueue();

        void printQueue();

        int QueueSize();

private:

        int size;

        Node* front;

        Node* rear;

};

Queue::Queue()

{

        size = 0;

        front = NULL;

        rear = NULL;

}

void Queue::enQueue(int n)

{

        Node* NewNode = new Node(n);

        if(size==0) // r == f

        {

               front = NewNode;

               rear = NewNode;

        }

        else // r != f

        {

               Node* temp = rear;

               rear = NewNode;

               rear->nextNode = temp;

               temp->prevNode = rear;

        }

        size++;

}

void Queue::deQueue()

{

        Node* temp = front;

        front = temp->prevNode;

        delete temp;

        size--;

}

 

int Queue::QueueSize() { return size; }

 

void Queue::printQueue()

{

        Node* temp = front;

        cout << "Queue List" << " (Queue Size : " << QueueSize() << " )" << endl;

        while(1)

        {

               cout << temp->data << endl;

               if(temp->prevNode == NULL)

                       break;

               temp = temp->prevNode;

        }

}

int main()

{

        Queue q;

        q.enQueue(3);

        q.enQueue(4);

        q.enQueue(5);

        q.deQueue();

        q.printQueue(); // 4 5

        q.enQueue(7);

        q.enQueue(2);

        q.deQueue();

        q.enQueue(1);

        q.printQueue(); // 5 7 2 1

        return 0;

}

 


신고

'Data Structure' 카테고리의 다른 글

List로 구현한 Queue  (0) 2013.01.31
Binary Trees  (0) 2012.11.07
CircularArray(환형 배열, queue)  (0) 2012.10.24
간단한 리스트 구현(단방향)  (0) 2012.09.08
Linked List(링크드 리스트)  (0) 2012.03.24
큐(Queue)  (0) 2012.03.02

+ Recent posts