How fast canwe sort?
C3
조원 : (조장) 11최수영
09권용현
09홍준표
10권희준
11전승협
2.
<요약 및 문제파악>
집합과 그 집합에서 뽑아낼 부분집합의 원소 개수를 입력받아서, 그 개수만큼의
원소를 가진 부분집합들을 모두 출력하는 프로그램 작성
<연구 배경>
프로젝트 진행을 위해 symmetric, reflexive, irreflexive ,행렬 의 기본개념을
연구하였다.
• The Fundamental Principle of Counting
덧셈 법칙 k개의 가능성이 있는 일이 독립적으로 시행될 수 있고, 또 각각의
경우의 수가 m1, m2, ..., mk 일 때, 가능한 전체의 경우의 수는 모두 m1 + m2
+ ... + mk이다. 이것을 합의법칙(the addition principle)이라고 한다.
• k-sample
S가 공집합이 아닌 집합일 때, 중복을 허용하고 순서를 고려하여 r개를
선택한 부분집합을 S의 r표본(r-sample)이라 한다.
S개의 원소의 개수를 n이라 하고, r표본의 개수를 구하여봅시다.
먼저 순서를 고려하므로 r개의 방을 먼저 순서대로 나열하고
□□□ ... □
각 방에는 S의 원소 n개 중에서 임의로 한 개를 선택할 수 있으므로 곱의
법칙에 대하여 n×n×...×n=nr
이며, 이것을 중복순열이라고 부른다.
• k-selection
원소의 개수가 n인 집단으로부터 중복을 허용하여 r개를 고르는 것을
r-선택(r-selection)이라 하고, 이를 중복조합이라고 한다.
이 때, r은 n보다 커도 무방하다. 또, r-선택 중에서 원소가 모두 다른 것을
우리는 r-조합이라고 부른다.
• k-permutations
집합 S의 r-sample 중에서 원소가 모두 다른 것들을 우리는
r-순열(r-permutation)이라고 부른다. 또, S의 원소의 개수가 r인 경우에
S의 r-순열은 단순히 순열(permutation)이라고 한다.
• k-combinations
n개의 원소를 갖는 집합 S로부터 r개의 서로 다른 원소를 순서를 고려하지
않고 선택한 집합을 S의 r-조합(r-combination) r-선택 중에서 원소가 모두
다른 것을 우리는 r-조합이라고 부른다.
3.
<프로젝트 진행일정>
과제수행기간: ___2___일 총____5___시간
1day (4/11) 2day (4/18)
*문제에 대한 분석 *초안에 대한 문제파악 및 대책 마련 토의 (최
(앞으로 나가야 할 방향에 대한 토의) 종 작성 방향 결정)
*업무 분담 *과제1 문제 해결방안 토의
자료조사팀 : 과제1에 대한 방법 조사 *코딩에 대한 문제점 보안으로 최종 코딩 완성
알고리즘팀 : 프로젝트 초안 짜기. *각 조원들의 자료를 모아 최종 보고서 작성
<업무 분담>
l 최종보고서 작성
최수영 <조장>
l 과제 1 수행
5
l 토의 첫날, 용어 정리
권용현 l 과제 1 에 대한 조사
5 l 과제 1 수행
l 프로젝트 코딩
홍준표
l 과제 1 수행
5
l 과제 1 에 대한 조사
권희준
l 과제 1 수행
4
l 프로젝트 코딩
전승협
l 과제 1 수행
5
4.
<프로젝트 진행과정>
<과제1>
질문 :10~29까지 두 자리 정수가 적힌 20장의 카드가 있다고 하자. 카드를 무작위로 섞었
다. 가장 큰 수가 나올 때까지 찾아서 이 카드를 테이블 위에 앞면이 위로 오도록 놓는다.
이 과정을 모든 카드를 찾을 때까지 반복한다.
1. 전체 카드를 몇 번 보아야 하는가?
2. 시간 복잡도?
해결 방법 :
1. 우선 2,3,4개의 카드를 비교하는 형태를 파악하여 규칙을 찾습니다.
v 2개의 카드를 정렬하기 위해 카드 사이에 1번의 비교를 해야 합니다.
v 3개의 카드를 정렬하기 위해 카드 사이에 비교하는 횟수는?
= 아직 정렬되지 않은 3개의 카드 사이에 2번의 비교 후 가장 큰 수를 맨 뒤에 위치
시킵니다.
= 정렬된 카드를 제외한 2개의 카드 사이에 1번의 비교를 합니다.
= 그러면 3개의 카드 사이의 비교 횟수는 1+2=3이 됩니다.
v 4개의 카드를 정렬하기 위해 카드 사이에 비교하는 횟수는?
= 아직 정렬되지 않은 4개의 카드 사이에 3번의 비교 후 가장 큰 수를 맨 뒤에 위치
시킵니다.
= 남은 3개의 카드 사이에 2번의 비교를 하고, 남은 카드 중 큰 수를 뒤쪽으로 위치
시킵니다.
= 다시 남은 2개의 카드 사이에 1번의 비교를 하고, 정렬합니다.
= 그러면 4개의 카드 사이의 비교 횟수는 1+2+3=6이 됩니다.
v 마찬가지로 5개 사이에는 1+2+3+4=10회 비교 6개 사이에는 1+2+3+4+5=15회 비교이
므로,
v n개의 카드 사이의 비교 횟수는 ⋯ 가 되는 것이지
요. (정렬 방법 중 “선택 정렬”이라는 방법이 있는데, 그 방법입니다.)
×
v 그러면 20개의 카드 사이의 비교 횟수는 ⋯ 회입니
다.
2. 시간 복잡도 : 일반적인 다항식에서의 시간 복잡도는 최고차항을 통해 따질 수 있습니다.
예를 들어 n에 대한 함수식 중 의 시간 복잡도는 최고차항만 남기
면 되므로, 이 됩니다.
한편 최고차항에 계수가 있는 경우입니다. n에 대한 함수식 중 의 시간 복잡도
는 최고차항의 계수를 삭제하여 이 됩니다.
이 문제에서 총 비교 수는 이므로, 시간 복잡도는 입니다.
5.
이렇게 풀었지만 교수님이제시한 방법대로도 해결해보았습니다.
방법1
전체카드를 몇 번 보아야 하는가?
최대210번, 최소20번
최대-> 1 .가장 큰 수가 나올 때까지 뒤집어 본다. 그 수를 뒤집어 놓는다. 20번
2. 두 번째 큰 수가 나올 때까지 뒤집어 본다. 그 수를 뒤집어 놓는다. 19번
...
3, 가장 작은 수가 나올 때 뒤집어 본다. 1번
20+19+...+2+1 = 210번
최소-> 1. 첫 장을 뒤집었을 때 가장큰수가 나온다. 1번
2. 두 번째 장을 뒤집었을 때 두 번때 큰수가 나온다. 1번
...
3. 마지막 장을 뒤집었을 때 가장 작은수가 나온다. 1번
1+1+...+1+1 = 20번
n = 카드 수일 때
최악의 경우는 어떻게 초기화 되었을 경우인가?
n(n+1)/2
최선의 경우는 어떻게 초기화 되었을 경우인가?
n
방법2
130번
1. 20장의 카드를 다 보고 십의 자리수가 1인 수과 2인수로 나눈다. 20번
2. 각 뭉치를 방법1로 정렬한다 55+55 = 110번
방법3
30번
1, 카드를 다 보고 두 번째 수가 같은 카드를 모은다. 20번
2. 10개의 뭉치를 한번씩 보고 첫 번째 수가 1인지 2인지 확인하고 뒤집어 놓는다. 10번
6.
<프로그램 완성>
#include <stdio.h>
#include<stdlib.h>
#include <string.h>
/*
배열 출력
*/
void print(char dar[], int N)
{
int i;
for(i=0; i < N; i++) {
printf("%c",dar[i]);
}
printf(",");
}
/*
주어진 문자들을 중복없이 num 개 조합
dar : 조합한 문자들의 배열
N : 조합할 개수
num : 조합한 개수
arr : 뽑히지 않은 m개 문자들의 배열
*/
void combi_nodup(char dar[], int N, int num, char arr[], int m)
{
if(num == N) {// 다 뽑았으면 출력
print(dar,N);
}
else if(N-num <= m){
int i;
for(i=0; i < m; i++)
{
dar[num] = arr[i]; // i 번째 요소 값을 뽑고,
combi_nodup(dar,N,num+1,arr+i+1,m-i-1); // 이후 문자들에서 나머지를
뽑음.
}