#문제

준규가 가지고 있는 동전은 총 N종류이고, 각각의 동전을 매우 많이 가지고 있다.

동전을 적절히 사용해서 그 가치의 합을 K로 만들려고 한다. 이때 필요한 동전 개수의 최솟값을 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N과 K가 주어진다. (1 ≤ N ≤ 10, 1 ≤ K ≤ 100,000,000)

둘째 줄부터 N개의 줄에 동전의 가치 Ai가 오름차순으로 주어진다. (1 ≤ Ai ≤ 1,000,000, A1 = 1, i ≥ 2인 경우에 Ai는 Ai-1의 배수)

출력

첫째 줄에 K원을 만드는데 필요한 동전 개수의 최솟값을 출력한다.

 

#작성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
int n,k;
int coinnum=0;
int coin[10];        //인덱스 1~10 사용
 
int main(){
    cin>>n>>k;
    for(int i=0; i<n; i++){
        cin>>coin[i];
    }
    
    for(int i=n-1; i>=0; i--){
        coinnum+=k/coin[i];
        k%=coin[i];
    }
    cout<<coinnum;
    return 0;
 
cs

##

'BOJ' 카테고리의 다른 글

BOJ 1931번 :: 회의실 배정  (0) 2019.12.18
BOJ 11657번 :: 타임머신  (0) 2019.12.15
BOJ 12865번 :: 평범한 배낭  (0) 2019.12.14
BOJ 9370번 :: 미확인 도착지  (0) 2019.12.13
BOJ 1912번 :: 연속합  (0) 2019.12.09

#문제

이 문제는 아주 평범한 배낭에 관한 문제이다.

한 달 후면 국가의 부름을 받게 되는 준서는 여행을 가려고 한다. 세상과의 단절을 슬퍼하며 최대한 즐기기 위한 여행이기 때문에, 가지고 다닐 배낭 또한 최대한 가치 있게 싸려고 한다.

준서가 여행에 필요하다고 생각하는 N개의 물건이 있다. 각 물건은 무게 W와 가치 V를 가지는데, 해당 물건을 배낭에 넣어서 가면 준서가 V만큼 즐길 수 있다. 아직 행군을 해본 적이 없는 준서는 최대 K무게까지의 배낭만 들고 다닐 수 있다. 준서가 최대한 즐거운 여행을 하기 위해 배낭에 넣을 수 있는 물건들의 가치의 최댓값을 알려주자.

입력

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)가 주어진다.

입력으로 주어지는 모든 수는 정수이다.

출력

한 줄에 배낭에 넣을 수 있는 물건들의 가치합의 최댓값을 출력한다.

 

#작성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <vector>
using namespace std;
 
int n, k;
vector<pair<intint> > item;
int d[100][100001];                        // 인덱스 0~99 사용 
 
void input(){
    scanf("%d %d"&n, &k);
    for(int i=0; i<n; i++){
        int w, v;
        scanf("%d %d"&w, &v);
        item.push_back(make_pair(w, v));
    }
}
 
int knapsack(int cur, int cap){
    if( cur == n ) return 0;
    int tmp = d[cur][cap];
    // 이 값이 이미 계산된 값이라면 저장된 값을 리턴 
    if( tmp != 0 ) return tmp;
    
    // 여유무게 >= 이번 아이템 무게일때
    // 이번 아이템을 담는 선택 vs 담지 않는 선택 중 value가 최대가 되는 선택을 한다. 
    if( cap>=item[cur].first ){
        tmp = max( knapsack(cur+1, cap-item[cur].first)+item[cur].second,
                    knapsack(cur+1, cap));
    }
    // 여유무게 < 이번 아이템 무게이면
    // 이 아이템은 절대로 담을 수없으므로 다음 아이템을 탐색한다. 
    else{
        tmp = knapsack(cur+1, cap);
    }
    return d[cur][cap] = tmp;
}
 
void solve(){
    printf("%d\n", knapsack(0, k));
}
 
int main(){
    input();
    solve();
    return 0;
}
cs

 

bottom up

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <bits/stdc++.h>
using namespace std;
 
int N;
int K;
int item[100][2];
int max_pack=0;
 
int main(){
    cin>>N>>K;
    for(int i=0; i<N; i++){
        cin>>item[i][0]>>item[i][1];
    }
    int *pack = new int[K+1];
 
    pack[0= 0;
    for(int i=0; i<N; i++){
        for(int x=K; x>=0; x--){
            if(x-item[i][0]>=0)
                pack[x] = max(pack[x], pack[x-item[i][0]]+item[i][1]);
            max_pack = max(max_pack, pack[x]);
        }
    }
    cout<<max_pack;
    return 0;
}
cs

?! 왜 무게를 0부터 시작했을땐 오류가 나고, K부터 시작해서 줄여나가면 제대로 되는거지

##

이번 물건을 배낭에 담을 수 있을 때 담는 선택, 담지 않는 선택 둘 다를 고려해야 하는 점이 중요한것같다.

 

아래 글을 참고해서 조금 더 공부해야지!

http://blog.naver.com/PostView.nhn?blogId=frankjune&logNo=221341520199&parentCategoryNo=&categoryNo=38&viewDate=&isShowPopularPosts=false&from=postView
아주 도움이 되었다. TOP-DOWN방식과 BOTTOM-UP방식 DP의 효율성에 대해서 생각해보아야겠다.

'BOJ' 카테고리의 다른 글

BOJ 11657번 :: 타임머신  (0) 2019.12.15
BOJ 11047번 :: 동전 0  (0) 2019.12.15
BOJ 9370번 :: 미확인 도착지  (0) 2019.12.13
BOJ 1912번 :: 연속합  (0) 2019.12.09
BOJ 9251번 :: LCS  (0) 2019.12.09

#문제

(취익)B100 요원, 요란한 옷차림을 한 서커스 예술가 한 쌍이 한 도시의 거리들을 이동하고 있다. 너의 임무는 그들이 어디로 가고 있는 지 알아내는 것이다. 우리가 알아낸 것은 그들이 s지점에서 출발했다는 것, 그리고 목적지 후보들 중 하나가 그들의 목적지라는 것이다. 그들이 급한 상황이기 때문에 목적지까지 우회하지 않고 최단거리로 갈 것이라 확신한다. 이상이다. (취익)

어휴! (요란한 옷차림을 했을지도 모를) 듀오가 어디에도 보이지 않는다. 다행히도 당신은 후각이 개만큼 뛰어나다. 이 후각으로 그들이 g와 h 교차로 사이에 있는 도로를 지나갔다는 것을 알아냈다.

이 듀오는 대체 어디로 가고 있는 것일까?

예제 입력의 두 번째 케이스를 시각화한 것이다. 이 듀오는 회색 원에서 두 검은 원 중 하나로 가고 있고 점선으로 표시된 도로에서 냄새를 맡았다. 따라서 그들은 6으로 향하고 있다.

입력

첫 번째 줄에는 테스트 케이스의 T(1 ≤ T ≤ 100)가 주어진다. 각 테스트 케이스마다

  • 첫 번째 줄에 3개의 정수 n, m, t (2 ≤ n ≤ 2 000, 1 ≤ m ≤ 50 000 and 1 ≤ t ≤ 100)가 주어진다. 각각 교차로, 도로, 목적지 후보의 개수이다.

  • 두 번째 줄에 3개의 정수 s, g, h (1 ≤ s, g, h ≤ n)가 주어진다. s는 예술가들의 출발지이고, g, h는 문제 설명에 나와 있다. (g ≠ h)

  • 그 다음 m개의 각 줄마다 3개의 정수 a, b, d (1 ≤ a < b ≤ n and 1 ≤ d ≤ 1 000)가 주어진다. a와 b 사이에 길이 d의 양방향 도로가 있다는 뜻이다.

  • 그 다음 t개의 각 줄마다 정수 x가 주어지는데, t개의 목적지 후보들을 의미한다. 이 t개의 지점들은 서로 다른 위치이며 모두 s와 같지 않다.

교차로 사이에는 도로가 많아봐야 1개이다. m개의 줄 중에서 g와 h 사이의 도로를 나타낸 것이 존재한다. 또한 이 도로는 목적지 후보들 중 적어도 1개로 향하는 최단 경로의 일부이다.

출력

테스트 케이스마다

  • 입력에서 주어진 목적지 후보들 중 불가능한 경우들을 제외한 목적지들을 공백으로 분리시킨 오름차순의 정수들로 출력한다.

 

#작성 코드

1.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#include <iostream>
#include <cstdio> 
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
 
int INF = 2000000000;
int T;                // 테스트케이스개수 
int n, m, t;        // 도시개수, 도로개수, 목적지후보개수 
int s, g, h;        // 출발지, 경유지1, 경유지2 
vector<pair<intint> > city[2001];        // 도시 간 연결 저장 
vector<int> dest;                        // 목적지 후보들 저장
 
vector<int> dijkstra(int start){
    priority_queue<pair<intint> > pq;
    // -거리, 도시번호, 두 경유지 경유 여부 저장.
    vector<int> shortest(n+1, INF);
    // 출발-출발거리 :0, 출발지점, 경유지 사이 도로 지났는지 큐에 push 
    pq.push(make_pair(0, start));
    shortest[start] = 0;
    
    while(!pq.empty()){
        int now = pq.top().second;
        int di = -pq.top().first;
        pq.pop();
        
        if( shortest[now] < di ) continue;
        // 현재 지점에 연결된 곳 차례로 방문. 
        for(int i=0; i<city[now].size(); i++){
            int next = city[now][i].first;
            int nextDist = city[now][i].second+di;
            
            // 출발지점->now->next 경유하는 도로가 알고있는 최단경로보다 짧은 경우 갱신. 
            if( shortest[next] >= nextDist ){
                shortest[next] = nextDist;
                pq.push(make_pair(-nextDist, next));
            }
        }
    }
    // start에서 다른 모든 정점으로의 최단거리를 담은 벡터를 리턴. 
    return shortest;
}
 
int main(){
    scanf("%d"&T);        // 테스트케이스 입력
    for(int i=0; i<T; i++){
         /*init*/
         for(int i=0; i<2001; i++){
             city[i].clear();
        }
        dest.clear(); 
        /*input*/
        scanf("%d %d %d"&n, &m, &t);
        scanf("%d %d %d"&s, &g, &h);
        // m개의 도로 입력. 
        for(int i=0; i<m; i++){
            int start, end, dist;
            scanf("%d %d %d"&start, &end&dist);
            city[start].push_back(make_pair(end, dist));
            city[end].push_back(make_pair(start, dist));
        }
        // t개의 목적지 후보 입력. 
        for(int i=0; i<t; i++){
            int x;
            scanf("%d"&x);
            dest.push_back(x);
        }
        // 목적지 후보들을 오름차순으로 정렬
        sort(dest.begin(), dest.end());
        
        /*solve*/
        vector<int> sS = dijkstra(s);
        vector<int> sG = dijkstra(g);
        vector<int> sH = dijkstra(h);
        
        // 시작~목적지 후보까지의 최단거리가 s-g-h-t 또는 s-h-g-t라면
// 경유지를 모두 지났으므로 출력한다.
        for(int i=0; i<dest.size(); i++){
            int sght = sG[s]+sG[h]+sH[dest[i]];
            int shgt = sH[s]+sH[g]+sG[dest[i]];
            int st = sS[dest[i]];
            if( st==sght || st==shgt ){
                printf("%d ", dest[i]);
            }
        }
        printf("\n");
    } 
    return 0;
}
cs

2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <cstdio> 
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
 
int T;
int n, m, t;
int s, g, h;
int INF = 2000000000;
vector< pair<intint> > city[2001];    // 인덱스 1~n을 사용한다. 
vector<int> dest;    //목적지 후보 저장
 
vector<int> dijkstra(int start){
    vector<int> shortest(n+1, INF);        // 인덱스 1~n을 사용. 
    shortest[start] = 0;
    priority_queue< pair<intint> > pq;
    pq.push(make_pair(0, start));
    
    while(!pq.empty()){
        int now = pq.top().second;
        int nowcost = -pq.top().first;
        pq.pop();
        
        for(int i=0; i<city[now].size(); i++){
            int next = city[now][i].first;
            int nextcost = nowcost + city[now][i].second;
            if( shortest[next] > nextcost ){
                shortest[next] = nextcost;
                pq.push(make_pair(-nextcost, next));
            }
        }
    }
    return shortest;
}
 
int main(){
    cin>>T;
    for(int i=0; i<T; i++){
        /*init & input*/
        for(int i=0; i<2001; i++)
            city[i].clear();
        dest.clear();
        cin>>n>>m>>t;
        cin>>s>>g>>h;
        for(int i=0; i<m; i++){
            int a, b, d;
            cin>>a>>b>>d;
            city[a].push_back(make_pair(b, d));
            city[b].push_back(make_pair(a, d));
        }
        for(int i=0; i<t; i++){
            int x;
            cin>>x;
            dest.push_back(x);
        }
        
        /*solve*/
        // 목적지 후보들을 오름차순 정렬한다. 
        sort(dest.begin(), dest.end());
        vector<int> startG = dijkstra(g);
        vector<int> startH = dijkstra(h);
        vector<int> startS = dijkstra(s);
        
        int sgh = startG[s]+startG[h];
        int shg = startH[s]+startG[h];
        for(int i=0; i<dest.size(); i++){
            int cur = dest[i];
            int sght = sgh+startH[cur];
            int shgt = shg+startG[cur];
            int st = startS[cur];
            if( sght==st){
                printf("%d ", cur);
            }
            else if (shgt==st){
                printf("%d ", cur);
            }
        }
        printf("\n");
    }
cs

 

##

틀렸다는 판정을 계속 받아서 코드를 새로 작성하고, 다른 사람들의 코드와도 비교해가며 해답을 찾았다.

처음 코드에서 틀렸던 점은, dijkstra(int start) 함수 내부의 shortest배열의 start인덱스 위치 값을 0으로 초기화해주지 않아서 최단경로를 찾지 못했던 것이었다.

두 번째 코드에서 틀렸던 점은 처음 코드의 틀린 점은 보완했지만, shortest 벡터의 인덱스를 1~n까지 사용하면서 0~n-1만큼만 INF로 초기화해서 문제가 발생했다.

각각의 소스 코드에서 빠트렸던 부분은 굵게 표시해뒀으니 꼭 다시 읽고 같은 실수 반복하지 않도록 하자.

초기 코드 형태에서 완전히 수정한 것

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
#include <iostream>
#include <cstdio> 
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;
 
int INF = 2000000000;
int T;                // 테스트케이스개수 
int n, m, t;        // 도시개수, 도로개수, 목적지후보개수 
int s, g, h;        // 출발지, 경유지1, 경유지2 
vector<pair<intint> > city[2001];        // 도시 간 연결 저장 
vector<int> dest;                        // 목적지 후보들 저장
 
vector<int> dijkstra(int start){
    priority_queue<pair<intint> > pq;
    // -거리, 도시번호, 두 경유지 경유 여부 저장.
    vector<int> shortest(n+1, INF);
    // 출발-출발거리 :0, 출발지점, 경유지 사이 도로 지났는지 큐에 push 
    pq.push(make_pair(0, start));
    shortest[start] = 0;
    
    while(!pq.empty()){
        int now = pq.top().second;
        int di = -pq.top().first;
        pq.pop();
        
        if( shortest[now] < di ) continue;
        // 현재 지점에 연결된 곳 차례로 방문. 
        for(int i=0; i<city[now].size(); i++){
            int next = city[now][i].first;
            int nextDist = city[now][i].second+di;
            
            // 출발지점->now->next 경유하는 도로가 알고있는 최단경로보다 짧은 경우 갱신. 
            if( shortest[next] >= nextDist ){
                shortest[next] = nextDist;
                pq.push(make_pair(-nextDist, next));
            }
        }
    }
    // start에서 다른 모든 정점으로의 최단거리를 담은 벡터를 리턴. 
    return shortest;
}
void input(){
    /*init*/
     for(int i=0; i<2001; i++){
         city[i].clear();
    }
    dest.clear(); 
    /*input*/
    scanf("%d %d %d"&n, &m, &t);
    scanf("%d %d %d"&s, &g, &h);
    // m개의 도로 입력. 
    for(int i=0; i<m; i++){
        int start, end, dist;
        scanf("%d %d %d"&start, &end&dist);
        city[start].push_back(make_pair(end, dist));
        city[end].push_back(make_pair(start, dist));
    }
    // t개의 목적지 후보 입력. 
    for(int i=0; i<t; i++){
        int x;
        scanf("%d"&x);
        dest.push_back(x);
    }
    // 목적지 후보들을 오름차순으로 정렬
    sort(dest.begin(), dest.end());
}
void solve(){
    vector<int> sS = dijkstra(s);
    vector<int> sG = dijkstra(g);
    vector<int> sH = dijkstra(h);
    
    // 시작~목적지 후보까지의 최단거리가 s-g-h-t 또는 s-h-g-t라면 경유지를 모두 지났으므로 출력한다. 
    for(int i=0; i<dest.size(); i++){
        int sght = sG[s]+sG[h]+sH[dest[i]];
        int shgt = sH[s]+sH[g]+sG[dest[i]];
        int st = sS[dest[i]];
        if( st==sght || st==shgt ){
            printf("%d ", dest[i]);
        }
    }
    printf("\n");
}
 
int main(){
    scanf("%d"&T);        // 테스트케이스 입력
    for(int i=0; i<T; i++){
         input();
         solve();
    } 
    return 0;
}
cs

'BOJ' 카테고리의 다른 글

BOJ 11047번 :: 동전 0  (0) 2019.12.15
BOJ 12865번 :: 평범한 배낭  (0) 2019.12.14
BOJ 1912번 :: 연속합  (0) 2019.12.09
BOJ 9251번 :: LCS  (0) 2019.12.09
BOJ 1504번 :: 특정한 최단 경로  (0) 2019.12.08

10.1 리스트 만들기

>>> a = [10, 20, 30, 40, 50]

>>> a

[10, 20, 30, 40, 50]

[] 값을 묶어주면 리스트가 된다. 값은 , 구분해준다.

리스트에 저장된 값은 요소(element)라고 한다.

 

10.1.1 리스트에 여러 가지 자료형 저장하기

하나의 리스트에 여러 가지 자료형을 섞어서 저장해도 된다.

>>> person = ['홍길동', 20, 180, True]

>>> person

['홍길동', 20, 180, True]

객체에 관련된 정보들을 하나로 묶어서 관리하기에 편리하다.

 

10.1.2 리스트 만들기

>>> a = []

>>> a

[]


>>> b = list()

>>> b

[]

리스트를 만들어 놓은 후에 값을 추가하는 방식으로 활용한다.

 

10.1.3 range 사용하여 리스트 만들기

range() 연속된 숫자를 생성하는 함수.

range(10) : 0부터 9까지 숫자를 생성한다.

>>> range(10)

range(0, 10)
# 리스트 = list(range(횟수))

# == list(range(0, 횟수))

>>> a = list(range(10))

>>> a

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 리스트 = list(range(시작, 끝))

>>> b = list(range(3, 7))

>>> b

[3, 4, 5, 6]
# range에 증가폭을 지정하면 해당 값만큼 증가하면서 숫자를 생성.

# 리스트 = list(range(시작, 끝, 증가폭))

>>> c = list(range(-4, 10, 2))

>>> c

[-4, -2, 0, 2, 4, 6, 8]

 

 

10.2 튜플 사용하기

튜플은 리스트처럼 요소를 일렬로 저장하지만, 안에 저장된 요소를 변경, 추가, 삭제할 없다.

-> 읽기 전용 리스트라고 생각하자.

# 튜플 = (값, 값, 값)

# 튜플 = 값, 값, 값

>>> a = (38, 21, 53, 63, 26)

>>> a

(38, 21, 53, 63, 26)


>>> a = 38, 21, 53, 63, 26

>>> a

(38, 21, 53, 63, 26)

 

튜플토 리스트처럼 여러 자료형을 동시에 저장할 있다.

>>> person = ('홍길동', 20, 180, True)

>>> person

('홍길동', 20, 180, True)

 

튜플은 요소가 절대 변경되지 않고 유지되어야 사용한다.

튜플을 만든 상태에서 요소를 변경하면 에러가 발생한다.

 

10.2.1. 요소가 들어있는 튜플 만들기

# 값 한 개를 괄호로 묶으면 튜플이 아니라 그냥 값이 된다.

>>> (38)

38

 

# 요소가 한개인 튜플 만들기

# 튜플 = (값, )

# 튜플 = 값,

>>> (38, )

(38, )

>>> 38,

(38, )

 

한개짜리 튜플이 필요한 이유 : 함수를 사용할 값이 아닌 튜플을 넣어야 하는 경우가 발생하는데, 값은 한개지만 튜플 형식으로 넣어야 (, ) 형태로 넣어준다.

 

10.2.2 range 사용하여 튜플 만들기

# 튜플 = tuple(range(횟수))

>>> a = tuple(range(4))

>>> a

(0, 1, 2, 3)

 

# 튜플 = tuple(range(0, 횟수))

>>> a = tuple(range(0, 4))

>>> a

(0, 1, 2, 3)

 

# 튜플 = tuple(range(시작, 끝, 증가폭))

>>> a = tuple(range(-2, 12, 4))

>>> a

(-2, 2, 6, 10)

 

10.2.3 튜플<->리스트 변경

# 리스트 -> 튜플

>>> a = [1, 2, 3]

>>> tuple(a)

(1, 2, 3)
# 튜플 -> 리스트

>>> a = (1, 2, 3)

>>> list(a)

[1, 2, 3]

 

 

+) list tuple안에 문자열을 넣으면

문자열의 문자 하나하나가 리스트, 튜플의 요소로 생성된다.

>>> a = list('Hello')

>>> a

['H', 'e', 'l', 'l', 'o']
>>> a = tuple('Hello')

>>> a

('H', 'e', 'l', 'l', 'o')

 

+) 리스트와 튜플 사용해서 변수 여러 만들기

>>> a, b, c = [10, 20, 40]

>>> print(a, b, c)

10 20 40

>>> d, e, f = (4, 7, 9)

>>> print(d, e, f)

4, 7, 9

 

리스트와 튜플의 요소를 변수 여러 개에 할당하는 것을 리스트 언패킹, 튜플 언패킹이라 한다.

>>> x = [1, 2, 3]

>>> a, b, c = x

>>> print( a, b, c )

1 2 3

>>> y = (4, 5, 6)

>>> d, e, f = y

>>> print(d, e, f)

4 5 6

 

# input().split()은 리스트를 반환한다. -> 리스트 언패킹 형식 사용 가능.

>>> input().split()

10 20

['10', '20']

>>> x = input().split()

10 20

>>> a, b = x

>>> print(a, b)

10 20
>>> hello = 'Hello, world!'

>>> hello = "Hello, world!"

>>> hello = '''Hello, world!'''

>>> hello = """Hello, world!"""

 

작은 따옴표, 따옴표, 작은 따옴표 3, 따옴표 3개로 묶어서 문자열을 나타낼 있다.

 

9.1.1 여러 줄로 문자열 사용하기

'''또는 """ 문자열을 묶어서 나타내면 여러 줄로 문자열을 저장할 있다.

>>> hello = '''Hello, world!

안녕하세요.

Python 입니다.'''

>>> print(hello)

Hello, world!

안녕하세요.

Python 입니다.

 

여러 줄로 문자열은 파이썬 셸에서보다는 .py스크립트 파일에서 많이 사용된다.

 

9.1.2 문자열 안에 작은 따옴표나 따옴표 포함하기

문자열 안에 ' 넣고 싶다면 " 문자열을 묶어서 표현해야 한다.

>>> s = "I'm good!"

>>> s

I'm good!

 

문자열 안에 " 넣고 싶다면 ' 문자열을 묶어서 표현해야 한다.

>>> s = 'He said "Hello"'

>>> s

He said "Hello"

 

작은 따옴표 안에 작은 따옴표를 넣거나, 따옴표 안에 따옴표를 넣을 없다.

하지만, 여러 줄로 문자열(''', """ 묶은 ) 가능하다.

single_quote = '''"안녕하세요."

'파이썬'입니다.'''


double_quote = """"Hello"

'Python'"""


double_quote2 = """Hello, 'Python'"""


print(single_quote)

print(double_quote)

print(double_quote2)
"안녕하세요."

'파이썬'입니다.

"Hello"

'Python'

Hello, 'Python'

결과가 출력된다.

 

+) 이스케이스 문자 사용

>>> s= 'Python isn\'t difficult'

"Python isn't difficult"

문자열 안에 ', "등의 특수 문자를 포함하기 위해 이스케이프 문자를 붙여서 사용할 있다.

boolean 값은 True, False 출력된다.

비교 연산 >, <, >=, <=, ==, != 결과도 True, False 출력된다.

 

문자열의 비교도 가능. (대소문자를 구분한다.)

>>> 'abc' == 'abC'

False

 

8.1.5 객체가 같은지 다른지 비교

== != 자체를 비교하고,

객체는 is is not으로 비교한다.

>>> 1 == 1.0

True

>>> 1 is 1.0            # type(1) == type(1.0) 결과와 같다.

False

>>> 1 is not 1.0       # type(1) != type(1.0) 결과와 같다.

True

 

  비교에 is 사용하면 안된다.

>>> a = -5

>>> a is -5

True


>>> a = -6

>>> a is -6

False

 

이유는 변수 a 존재하는 상태에서 다른 값을 할당하면 메모리 주소가 달라질 있기 때문이다.

-> 다른 객체가 되기 때문에 값이 같더라도 is 비교하면 False 나온다.

=> 값을 비교할 때는 == != 연산자를 사용해야한다.

 

 

8.2 논리 연산자

and, or, not 있다.

비교 연산자와 논리 연산자를 혼용한다면 비교 연산자, 논리 연산자 순서로 판단한다.

 

+) 정수, 실수, 문자열을 bool 만들기.

bool(정수)

bool(실수)

bool('문자열')

정수 0, 실수 0.0, 문자열 '', "" 제외한 모든 값을 True 바꾼다.

 

+) 논리 연산에서의 단락 평가

단락 평가(short-circuit evalution) : 번째 값만으로 결과가 확실하면 다음 값들 확인 없이 결과값 정하는 .

>>> 'Python' and True

True

>>> True and 'Python'

'Python'

코드의 의미는 같지만 결과값이 다르게 나타나는 이뉴는,

파이썬에서 논리 연산자는 마지막으로 단락 평가를 실시한 값을 그대로 반환하기 때문이다.

-> 논리 연산자는 무조건 불을 반환하지 않는다.

 

>>> False and 'Python'

False

>>> 0 and 'Python'

0


>>> True or 'Python'

True

>>> 'Python' or True

'Python'

or연산자에서 번째 값만으로 결과가 결정되므로 번째 값을 리턴.

 

>>> False or ''

''

만약 번째 값까지 확인해야 한다면 번째 값을 리턴.

+ Recent posts