반응형

문제링크: https://www.acmicpc.net/problem/1389

 

1389번: 케빈 베이컨의 6단계 법칙

첫째 줄에 유저의 수 N (2 ≤ N ≤ 100)과 친구 관계의 수 M (1 ≤ M ≤ 5,000)이 주어진다. 둘째 줄부터 M개의 줄에는 친구 관계가 주어진다. 친구 관계는 A와 B로 이루어져 있으며, A와 B가 친구라는 뜻이다. A와 B가 친구이면, B와 A도 친구이며, A와 B가 같은 경우는 없다. 친구 관계는 중복되어 들어올 수도 있으며, 친구가 한 명도 없는 사람은 없다. 또, 모든 사람은 친구 관계로 연결되어져 있다.

www.acmicpc.net

 

6다리면 건너면 세상사람들을 다 알 수 있다~ 이런 느낌의 문제였습니다.

당연히 탐색이라면 dfs, bfs를 먼저 생각하셔야 합니다.  문제 조건으로 유저의 수 N (2 ≤ N ≤ 100)과 친구 관계의 수 M (1 ≤ M ≤ 5,000)입니다. 비교적 큰 수이기 때문에 dfs보다는 bfs를 먼저 생각했습니다. 

 

각각의 n번에서 최적탐색을 통해서 가장 빨리 도달하는 관계의 합을 더해주면 되는 방식이였습니다.

 

 

 

 

정답코드입니다.  bfs코드이고 4ms 정도의 시간이 걸립니다. 풀면서도 살짝 긴가민가 했습니다.

왜냐하면 O(n*m*n*큐)이고  대략 50,000,000 이상의 반복연산을 하기때문입니다. 1억번에는 훨씬 못미치지만 반복을 재외한 큐이므로 큐자체도 100번은 반복하지 않을까하는 생각때문입니다.

다행히 문제는 통과했습니다. ( 1초에 1억번이라는게 정확한 연산은 아니기도 하고 큐에 대해서 제가 놓치고 있는 부분이 있기에 통과된것같습니다.)

#include <iostream>
#include <cstring>
using namespace std;

int n = 0, m = 0;
int arr[5001][2];
int visited[5001];
int result = 1000000000,result_index =-1;
int bfs(int num) {
	int val = 0;
	int que[5000];
	
	for (int i = 1; i <= n; i++) {
		if (num == i) continue;
		memset(que, 0, 5000);
		memset(visited, 0, 5001);
		int started = 0, ended = 0;

		que[ended++] = num;
		visited[num] = 1;
		while (ended != started) {
			int a = que[started++];
			if (a == i) {
				val += visited[a] - 1;
				break;
			}
			for (int j = 0; j < m; j++) {
				if (arr[j][0] == a && !visited[arr[j][1]]) {
					que[ended++] = arr[j][1];
					visited[arr[j][1]] = visited[a] + 1;
				}
				else if (arr[j][1] == a && !visited[arr[j][0]]) {
					que[ended++] = arr[j][0];
					visited[arr[j][0]] = visited[a] + 1;
				}
			}
			

		}
	}

	return val;
}

int main() {
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> arr[i][0] >> arr[i][1];


	for (int i = 1; i <= n; i++) { //1~n번까지의 경로를 탐색
		int val = bfs(i);
		if (result > val) result = val, result_index = i;
	}
	cout << result_index << endl;
}

 

근데 생각해보니 더욱 효율적인 방법이 있었습니다. 

굳이 bfs문에서 n번 반복해줄 필요가 없었습니다...

어차피 while문이 한번다 돌고나면 visited엔 모든 인덱스별 최단경로값이 들어가있게 됩니다. 

친구 관계는 중복되어 들어올 수도 있으며, 친구가 한 명도 없는 사람은 없다. 또, 모든 사람은 친구 관계로 연결되어져 있다.

이 문제조건 때문입니다.

 

수정코드입니다.

시간도 0ms로 줄었습니다. 

#include <iostream>
#include <cstring>
using namespace std;

int n = 0, m = 0;
int arr[5001][2];
int visited[5001];
int result = 1000000000,result_index =-1;
int bfs(int num) {
	int val = 0;
	int que[5000];


	memset(que, 0, 5000);
	memset(visited, 0, 5001);
	int started = 0, ended = 0;

	que[ended++] = num;
	visited[num] = 1;
	while (ended != started) {
		int a = que[started++];

		for (int j = 0; j < m; j++) {
			if (arr[j][0] == a && !visited[arr[j][1]]) {
				que[ended++] = arr[j][1];
				visited[arr[j][1]] = visited[a] + 1;
			}
			else if (arr[j][1] == a && !visited[arr[j][0]]) {
				que[ended++] = arr[j][0];
				visited[arr[j][0]] = visited[a] + 1;
			}
		}

	}

	for (int i = 1; i <= n; i++)
		val += visited[i] - 1;


	return val;
	
}

int main() {
	cin >> n >> m;
	for (int i = 0; i < m; i++)
		cin >> arr[i][0] >> arr[i][1];


	for (int i = 1; i <= n; i++) { //1~n번까지의 경로를 탐색
		int val = bfs(i);
		if (result > val) result = val, result_index = i;
	}
	cout << result_index << endl;
}

 

 

dfs코드입니다. 다른 분의 코드를 참고해서 만들었습니다. 216ms로 시간이 오래걸립니다. 어느 것이 더욱 좋다 이 것보다는 자기한테 편한코드로 ac를 받으면 되는거라고 생각합니다. dfs의 장점은 명료하고 직관적이라는 것입니다. 다음뻔에는 dfs로 풀어야하는 문제를 리뷰하겠습니다. 모두 화이팅 :) 

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define MAX 102
#define INF 987654321
using namespace std;

int n,m;
int a,b;
int ans,res,step;
int person;

bool check[MAX];
vector<int> v[MAX];

void dfs(int ind,int goal,int cnt){
    if(ind == goal){
        step = min(step,cnt);
        return;
    }
    for(int i=0; i<v[ind].size(); i++){
        if(!check[v[ind][i]]){
            check[ind] = true;
            dfs(v[ind][i],goal,cnt+1);
            check[ind] = false;
        }
    }
}

int main(int argc, const char * argv[]) {
    // cin,cout 속도향상
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    // 입력
    cin >> n >> m;
    for(int i=0; i<m; i++){
        cin >> a >> b;
        v[a].push_back(b);
        v[b].push_back(a);
    }
    // 탐색
    ans = INF;
    for(int i=1; i<=n; i++){
        memset(check, false, sizeof(check));
        res = 0;
        for(int j=1; j<=n; j++){
            step = INF;
            if(i==j) continue;
            else{
                dfs(i,j,0);
                res += step;
            }
        }
        // 최소인지 검사
        if(ans > res){
            ans = res;
            person = i;
        }else if(ans == res){
            person = min(person, i);
        }
    }
    cout << person << endl;
}
반응형

'알고리즘 > BFS' 카테고리의 다른 글

[백준] 2206-벽 부수고 이동하기(C++)  (0) 2020.04.03
[백준] 8061-Bitmap  (0) 2020.03.26
[백준] 9205-맥주 마시면서 걸어가기(C++)  (0) 2020.03.12
[백준] 5014-스타트링크(C++)  (1) 2020.03.12
[백준] 2589-보물섬(C++)  (0) 2020.03.08
반응형

문제링크:https://www.acmicpc.net/problem/11650

 

11650번: 좌표 정렬하기

첫째 줄에 점의 개수 N (1 ≤ N ≤ 100,000)이 주어진다. 둘째 줄부터 N개의 줄에는 i번점의 위치 xi와 yi가 주어진다. (-100,000 ≤ xi, yi ≤ 100,000) 좌표는 항상 정수이고, 위치가 같은 두 점은 없다.

www.acmicpc.net

 

전형적인 정렬문제입니다.

sort함수를 사용하여 구현하였습니다.

 

사용법을 모르신다면 아래링크를 참고해주세요.

https://gusdnr69.tistory.com/52?category=765773

 

sort함수 사용법

1. 헤더 선언 #include 2. sort( start, end) or sort( start, end, compare) ex) sort(arr, arr+n) sort(arr, arr+n,cmp) 시작주소와 끝주소 그리고 cmp함수가 필요합니다. sort( start, end) -> 이..

gusdnr69.tistory.com

 

그리고 결과값을 여러개 출력할때 endl을 사용하지 않는 습관을 기릅시다. ('\n' 사용을 지향합시다.)

 

정답코드입니다.

#include <iostream>
#include <algorithm>
using namespace std;
struct info {
	int y;
	int x;
};

bool cmp(info a, info b) {
	if (a.x < b.x)
		return true;
	else if (a.x == b.x)
		if (a.y < b.y)
			return true;
	return false;
}
int n = 0;
info arr[100001];
int main() {
	cin >> n;
	for (int i = 0; i < n; i++)
		cin >> arr[i].x >> arr[i].y;
	sort(arr, arr + n, cmp);
	for (int i = 0; i < n; i++)
		cout << arr[i].x << ' ' << arr[i].y << '\n';
}
반응형
반응형

 

upper_bound 와 lower_bound 함수는 정렬된 배열에서 원하는 값의 위치의 인덱스를 반환하는 함수 입니다.

 

#include <algorithm> 라이브러리에 존재합니다. 

 

사용 예시입니다. 선행조건은 꼭 정렬되어있는 배열을 넣어야합니다.

int val = lower_bound(arr, arr + n, num ) - arr ;
int val = upper_bound(arr, arr + n, num ) - arr ;

위처럼 사용하고 lower_bound는 arr배열의 0~n까지중  num값인덱스 중 제일 작은 값을 반환 합니다. 

upper_bound는 arr배열의 0~n까지중 num보다 큰 가장작은 값의 인덱스 값을 반환합니다.

 

 

즉 1 2 3 3 3 3 4 배열에서 num=2인 lowerbound는 1을 반환, upperbound는 2를 반환하는 형태입니다. (2값의 인덱스 1, 3값의 인덱스 2)

 

 

연습문제 링크:https://www.acmicpc.net/problem/3020

 

3020번: 개똥벌레

문제 개똥벌레 한 마리가 장애물(석순과 종유석)로 가득찬 동굴에 들어갔다. 동굴의 길이는 N미터이고, 높이는 H미터이다. (N은 짝수) 첫 번째 장애물은 항상 석순이고, 그 다음에는 종유석과 석순이 번갈아가면서 등장한다. 아래 그림은 길이가 14미터이고 높이가 5미터인 동굴이다. (예제 그림) 이 개똥벌레는 장애물을 피하지 않는다. 자신이 지나갈 구간을 정한 다음 일직선으로 지나가면서 만나는 모든 장애물을 파괴한다. 위의 그림에서 4번째 구간으로 개똥벌레

www.acmicpc.net

직접 이분탐색을 구현해서 풀어도 되지만 upper_bound, lower_bound 을 사용하는데 좋은 예제이기 때문에 가져왔습니다. 

 

문제 해설:https://gusdnr69.tistory.com/59

 

[백준] 3020-개똥벌레(C++)

문제링크:https://www.acmicpc.net/problem/3020 3020번: 개똥벌레 문제 개똥벌레 한 마리가 장애물(석순과 종유석)로 가득찬 동굴에 들어갔다. 동굴의 길이는 N미터이고, 높이는 H미터이다. (N은 짝수) 첫 번째..

gusdnr69.tistory.com

화이팅입니다! :)

반응형

'프로그래밍 언어 > C++' 카테고리의 다른 글

c++ 우선순위 큐 priority_queue 사용법  (0) 2020.07.29
C++ sort함수 invalid comparator 오류  (0) 2020.05.04
C++ memset 사용법  (0) 2020.05.03
C++ math사용법 총정리  (0) 2020.03.13
sort함수 사용법  (0) 2020.03.13
반응형

문제링크:https://www.acmicpc.net/problem/3020

 

3020번: 개똥벌레

문제 개똥벌레 한 마리가 장애물(석순과 종유석)로 가득찬 동굴에 들어갔다. 동굴의 길이는 N미터이고, 높이는 H미터이다. (N은 짝수) 첫 번째 장애물은 항상 석순이고, 그 다음에는 종유석과 석순이 번갈아가면서 등장한다. 아래 그림은 길이가 14미터이고 높이가 5미터인 동굴이다. (예제 그림) 이 개똥벌레는 장애물을 피하지 않는다. 자신이 지나갈 구간을 정한 다음 일직선으로 지나가면서 만나는 모든 장애물을 파괴한다. 위의 그림에서 4번째 구간으로 개똥벌레

www.acmicpc.net

 

정렬문제입니다.

 

우선 일반적으로 생각할 수 있는 nXh 번 반복하여 값을 구하는 결과는 오답입니다. (시간초과)

 

O(n*h) = 200000 X 500000 번 반복하게 됩니다. 대략 1억번 반복에 1초라고 가정할때 당연한 결과 입니다.

 

완전탐색이 안된다면 고려해야할 것은 dp 혹은 그리디적 관점입니다. dp를 사용하기에는 결과값들 사이에 연관이 전혀 없습니다. 

 

정렬을 하고 결과값을 구할때 O(n)의 과정을 O(lgn)으로 줄일 수 있습니다. 

 

그방법은 이분탐색의 개념을 이용하는 것입니다. 정렬되어있는 상태라면 해당 높이를 기준으로 더큰 값들이 몇개 있는지 작은 값들이 몇개있는지 판단하는데 있어 평균적으로 lgn번의 탐색으로 값을 알 수 있습니다. 

 

직접구현해도 좋지만 C++의 lowerbound, upperbound를 사용해보겠습니다. 

 

사용 예시입니다. 선행조건은 꼭 정렬되어있는 배열을 넣어야합니다.

int val = lower_bound(arr, arr + n, num ) - arr ;
int val = upper_bound(arr, arr + n, num ) - arr ;

위처럼 사용하고 lower_bound는 arr배열의 0~n까지중  num값인덱스 중 제일 작은 값을 반환 합니다. 

upper_bound는 arr배열의 0~n까지중 num보다 큰 가장작은 값의 인덱스 값을 반환합니다.

즉 1 2 3 3 3 3 4 배열에서 num=2인 lowerbound는 1을 반환, upperbound는 2를 반환하는 형태입니다.

 

 

 

정답코드입니다. 

#include <iostream>
#include <algorithm>
using namespace std;
int arr[100001] = { 0 };
int arr2[100001] = { 0 };
int n, h;
int result = 200001, result_cnt = 0;


int main() {
	cin >> n >> h;

	for (int i = 0; i < n/2; i++) 
		cin >> arr[i ] >> arr2[i];
		
	sort(arr, arr + (n / 2));
	sort(arr2, arr2 + (n / 2));


	for (int i = 1; i <= h; i++) {

		int val = lower_bound(arr, arr + (n / 2), i ) - arr ;
		val += upper_bound(arr2, arr2 + (n / 2), h-i ) - arr2 ;
		val = n - val;

		if (result == val)
			result_cnt++;
		else if (result > val) { 
			result = val;
			result_cnt = 1;
		}
	}

	cout << result << ' ' << result_cnt << endl;

}
반응형

'알고리즘 > 기타' 카테고리의 다른 글

[백준] 11000-강의실 배정(C++)  (0) 2021.05.25
[백준] 1068-트리(C++)  (0) 2021.05.21
[백준] 1436-영화감독 숌(C++)  (0) 2020.04.02
[백준] 14570-나무 위의 구슬(C++)  (0) 2020.03.13
[백준] 15953-상금 헌터  (0) 2020.02.01
반응형

문제링크: https://www.acmicpc.net/problem/2225

 

2225번: 합분해

첫째 줄에 답을 1,000,000,000으로 나눈 나머지를 출력한다.

www.acmicpc.net

 

생각하는 과정이 필요한 문제였습니다. 각각의 결과값들을 순차대로 구하다 보면 규칙을 찾을 수 있습니다.

점화식만 구하면 쉽게 구현할 수 있는 문제였습니다.

 

n = 5 k = 4 의 예제를 살펴보겠습니다.

 

0 1 2 3 4 5
dp[1] 0 0 0 0 0 1
dp[2] 1 1 1 1 1 1
dp[3] 6 5 4 3 2 1
dp[4] 21 15 10 6 3 1

dp[k]은 dp[k][0] ~ dp[k][n]의 합이 됩니다. 그리고 각각의 dp[k][i] 는 dp[k-1][i] ~ dp[k-1][n] 까지의 합이 됩니다. 

비교적 쉽게 점화식을 구할 수 있습니다. 

 

그래서 ex) 5 4의 결과값은 21+15+10+6+3+1 = ? 이 되겠죠 ㅎㅎ

 

 

 

 

 

 

그다음으로 주의하셔야 할 것은 %연산을 해주는 위치와 숫자 범위입니다. 매번 dp[k-1][i] ~ dp[k-1][n] 의 연산마다 %1000000000연산을 해줘도 해당문제에서는 상관없습니다. 하지만 조금더 컴팩트 하게 코딩하기 위해서 dp[k][i] 에서만 %1000000000연산을 해주고 싶었습니다. 

 

근데 만약 dp[k-1] 의 합이 다 10^9를 초과해서 오버플로우가 난다면, 에러가 날 수 밖에 없습니다. 그래서 long long 을 사용해서 배열을 구현했습니다.

 

 

 

아래는 정답코드입니다. :) 직접 표를 작성해보시고 점화식을 시그마형태로 구하고 구현해보세요! 화이팅

 

#include <iostream>
using namespace std;
long long dp[202][202] = { 0 };
int n, k;
long long result = 0;

int main() {
	cin >> n >> k;
	dp[1][n] = 1; // 초기값 설정
	for (int i = 1; i <= k; i++) {		
		for (int j = 0; j <= n; j++) {
			for (int u = j; u <= n; u++)
				dp[i][j] += dp[i - 1][u];
			dp[i][j] %= 1000000000;
		}
	}
	
	for (int i = 0; i <= n; i++)
		result += dp[k][i];
	result %= 1000000000;
	cout << result << endl;
}
반응형
반응형

문제링크:https://www.acmicpc.net/problem/11722

 

11722번: 가장 긴 감소하는 부분 수열

수열 A가 주어졌을 때, 가장 긴 감소하는 부분 수열을 구하는 프로그램을 작성하시오. 예를 들어, 수열 A = {10, 30, 10, 20, 20, 10} 인 경우에 가장 긴 감소하는 부분 수열은 A = {10, 30, 10, 20, 20, 10}  이고, 길이는 3이다.

www.acmicpc.net

 

전형적인 LIS 문제였습니다. 

LIS 개념을 아신다면 어렵지 않은 문제였습니다.

그나마 주의해야 할 점은 이전 dp값을 전부 확인해봐야한다는 것입니다. 

바로 이전의 자신보다 큰값만 비교할 경우 예외가 발생합니다. 

 

Ex) 5

     10 5 4 6 3

 

정답코드입니다. 화이팅 :)

#include <iostream>
using namespace std;
int dp[1001] = { 0 };
int arr[1001] = { 0 };
int n,num,result =0;
int main() {
	cin >> n;

	for (int i = 0; i < n; i++) {
		int maxed = 0;
		cin >> arr[i];
		for (int j = 0; j < i; j++) {
			if (arr[i] < arr[j] && maxed < dp[j])
				maxed = dp[j];
		}
		dp[i] = maxed + 1;
	}
	
	for (int i = 0; i < n; i++) {
		if (result < dp[i]) result = dp[i];
	}
	cout << result << endl;
}
반응형

'알고리즘 > DP' 카테고리의 다른 글

[백준] 11051-이항계수2  (0) 2020.03.26
[백준] 2225-합분해(C++)  (0) 2020.03.21
[백준] 2352-반도체 설계(C++)  (0) 2020.03.02
[백준] 11055-가장 큰 증가 부분 수열  (0) 2020.02.01
[백준] 9461-파도반 수열  (0) 2020.02.01
반응형

파이썬을 사용할 때 기본으로 제공되는 라이브러리만 사용되지 않고 많은 기능을 제공하는 라이브러리들을 추가 하여 사용하게 됩니다. 이러한 라이브러리가 특정 프로젝트에서만 사용되거나 프로젝트를 배포할 때 필요한 라이브러리만 포함시켜 배포하고 싶을 경우가 있을 것입니다.

 

이럴때 사용할 수 있는것이 가상환경(virtualenv) 입니다. 가상환경을 만들고, 그 가상환경에서 라이브러리를 추가하면 추가된 라이브러리는 그 가상환경에서만 사용 되어집니다.

 

우선 패스설정이 완료되었다는 가정하에 진행하겠습니다. (path설정을 통해 파이썬이 다른 경로 폴더의 .py들을 실행시킬 수 있게 만드는 과정입니다. 

 

C:\>esay_install pip

 

파이썬 패키지 관리자인 pip.exe 파일을 Python 3.4 버전부터 미리 포함되어 있습니다. 이전 버전을 사용한다면 easy_install 프로그램을 이용해서 pip.exe 를 먼저 설치합니다.

 

여러개의 파이썬 프로젝트를 관리하면서 각 프로젝트마다 사용되는 라이브러리가 충돌을 한다던가 하는 경우에도 가상환경을 사용하여 분리할 수 있습니다.

 

가상 환경 없이 설치한 파이썬 라이브러리는 전역으로 설치됩니다. 이렇게 설치한 라이브러리는 모든 사용자와 모든 프로젝트에서 사용할 수 있습니다.

 

가상환경을 다음과 같이 설치합니다.

 

C:\>pip install virtualenv

 

이제 가상환경을 만들어 봅니다. 가상환경 파일이 생성될곳을 C:\>workspace\python 으로 하겠습니다. 다음 명령을 실행합니다.

 

C:\>workspace\python>virtualenv ProjectEnv

 

이 명령은 새 환경 ProjectEnv 를 만듭니다. 만든 새 환경을 사용하려면 먼저 활성화해야 합니다. 새환경 폴더 아래 Scripts 폴더 아래에 activate.bat 파일을 실행합니다.

 

C:\>workspace\python>cd ProjectEnv\Scripts

C:\>workspace\python\ProjectEnv\Scripts>activate

 

환경을 활성화하면 환경의 이름이 명령 프롬프트에 표시되어 현재 가상 환경에 있음을 알립니다. 가상 환경에서 라이브러리를 설치하거나 스크립트를 실행하면 그 환경에만 영향이 있습니다.

 

(ProjectEnv) C:\workspace\python\ProjectEnv\Scripts>python

>>>^Z

 

deactivate 명령으로 환경에서 떠날 수 있습니다. 다시 가상환경으로 들어가기 위해서는 activate 명령을 다시 실행하면 됩니다.

 

(ProjectEnv) C:\workspace\python\ProjectEnv\Scripts>deactivate



출처: https://offbyone.tistory.com/74 [쉬고 싶은 개발자]


 

요약정리

 

가상환경 설치 & 실행
python - m venv (가상환경 이름)
source (가상환경이름)/scrips/activate

<->deactivate

 

라이브러리 설치시 

pip install ~~ 

반응형
반응형

Python은 1991년 프로그래머인 귀도 반 로섬(Guido van Rossum)이 발표한 고급 프로그래밍 언어로, 플랫폼 독립적이며 인터프리터식, 객체지향적, 동적 타이핑(dynamically typed) 대화형 언어이다. 파이썬이라는 이름은 귀도가 좋아하는 코미디 〈Monty Python’s Flying Circus〉에서 따온 것입니다. 

 

즉 프로그래밍 언어입니다. 

 

가장 큰 특징은 인터프리터 언어라는 것입니다.

소스 코드를 기계어로 컴파일해서 실행파일을 만들고 실행하는 컴파일 언어와는 다르게 인터프러터 언어는 코드를 한 줄씩 읽어 내려가며 실행하는 프로그래밍 언어입니다. 인터프리터 방식을 쓰는 프로그래밍 언어는 많은데 대표적인 것이 Python입니다. 파이썬은 그 외에도 정적타입, 동적타입 모두 사용가능하다는 특성이 있습니다.

 

인터프리터 언어의 장단점

인터프리터는 실행 시마다 소스 코드를 한 줄씩 기계어로 번역하는 방식이기 때문에 실행 속도는 컴파일 언어보다 느리다. 그렇다면 왜 사용할까? 인터프리터 언어는 프로그램 수정이 간단하다는 장점이 있습니다. 컴파일러는 소스 코드를 번역해서 실행 파일을 만들기 때문에 프로그램에 수정 사항이 발생하면 소스 코드를 다시 컴파일해야 한다. 하지만 인터프리터는 소스 코드를 수정해서 바로 실행시킬 수 있습니다.

 

장점

  • 배우기 쉬워서 학습용으로 좋다.
  • 공동 작업과 유지 보수가 아주 쉽고 편해서 생산성이 높고 실사용률도 높다.
  • 읽고 쓰기 쉽다.

단점

  • 느리다.

Python 동작절차

Python의 구현체 CPython

일반적으로 python이 C로 구현되어 있다고 알려져있는데 그 구현체가 CPython이다. 가장 처음 만들어진 python의 구현체이고 Python.org 에서 다운 받으면 CPython을 받는 것입니다. 다른 구현체들과 비교해서 언급할 때 주로 CPython이라고 표기하는데 Python을 C언어로 구현한 구현체를 의미합니다.

CPython은 인터프리터 이면서 컴파일러 입니다. 우리가 작성하는 Python 코드를 bytecode로 컴파일 하고 실행합니다. 다시 말해, python 코드를 C언어로 바꾸는 것이 아니라 컴파일하여 bytecode로 바꾸고 그 다음에 interpreter(virtual machine)가 실행합니다.

(CPython 인터프리터 실행 중에 단점이 있는데 GIL(global interpreter lock)을 사용한다는 것이다. bytecode를 실행할 때에 여러 thread를 사용할 경우, 전체에 lock 을 걸어서 한번에 단 하나의 thread 만이 python object에 접근하도록 제한한 것이다. 하지만 single thread일 때는 문제가 없고 GIL의 단점을 보안하기 위한 방법들이 존재하고 있어서 GIL로 인한 불편함을 느낄 가능성은 거의 없다고 한다.)

 

Jython

python 코드를 java 바이트코드로 만들어 JVM에서 실행할 수 있도록 한다. .py 파일을 .class파일로 컴파일 한다.

 

pypy

python 자체로 구현. JIT 컴파일 도입하여 CPython 보다 빠르다.

 

(JIT(just-in-time) 컴파일 이란 프로그램을 실행하기 전에 컴파일 하는 대신, 프로그램을 실행하는 시점에서 피료한 부분을 즉석으로 컴파일하는 방식. 보통 인터프리터 언어의 성능 향상을 목적으로 도입하는 경우가 많다. 인터프리트 하면서 자주 쓰이는 코드를 캐싱하기 때문에 인터프리터의 느린 실행 속도를 개선할 수 있다. JVM에서도 바이트코드를 기계어로 번역할 때 JIT 컴파일러를 사용한다.)

 

 

 

출처:https://cjh5414.github.io/about-python-and-how-python-works/

 

Python에 대하여, Python은 어떻게 동작하는가? Python의 장단점

Jihun's Development Blog

cjh5414.github.io

 

반응형

+ Recent posts