2021년 4월 4일 일요일

문자열의 정렬 (C언어)

순차 정렬

기본 정렬은 알고리즘은 아래와 같습니다.


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
 
#include <stdio.h>
 
#define N_MAX 10
 
int data[]={9,3,1,4,5,3,4,6,2,4};
 
void swap(int i,int j)
{
    int temp;
    temp = data[i];
    data[i]=data[j];
    data[j]=temp;
}
 
void print()
{
    int i;
    for(i=0;i<N_MAX;i++){
        printf("%d ",data[i]);
    }
    printf("\n");
}
 
int main()
{
    int i,j;
    for(i=0;i<N_MAX;i++){
        for(j=i+1;j<N_MAX;j++){
            if(data[i]>data[j]){
                swap(i,j);
            }         
        }
    }
    
    print();
    return 0;
}
cs

실행화면

1
1 2 3 3 4 4 4 5 6 9
cs


이것을 문자열 정렬로 변환해보겠습니다.

방법은 2가지가 있습니다. 

1. 실제 데이터를 변경하는 방법

2. 데이터를 변경하지 않고 인덱스만 정렬하는 방법


먼저 1번에 대해서 알아보겠습니다.

선행 지식으로 두가지를 알아야 합니다.

1. 문자열의 비교 방법 - strcmp 함수를 사용하던가 직접 만들어야합니다.

2. 문자열 복사


문자열 정렬 - 실제 데이터를 변경하는 방법

위의 정수 정렬에서 조건 검사를 하는 부분은 아래와 같습니다.

if(data[i]>data[j]){

이것은 아래와 같이 변경도 가능합니다. 중학교 수준의 방정식입니다.

if(data[i]-data[j]>0){

그럼 정수의 뺄셈을 해주는 diff 함수가 존재한다면 아래와 같이 변형이 가능합니다.

if(diff(data[i],data[j])>0){

문자열에서도 위와 같이 동일한 함수를 사용합니다.

문자열 비교 함수 diff 는 값이 클때는 +값 작을때는 - 값 같을때는 0 을 리턴하도록 제작합니다. 

diff 함수를 사용하는곳은 위에서 한 곳 뿐인데 0보다 큰지 작은지의 결과만 사용하므로 제작은 1,0,-1이 넘어가도록 제작합니다.


1
2
3
4
5
6
7
8
9
10
11
int diff(char *a,char *b){
    int i;
    for(i=0;;i++){
        if(a[i]==0 && b[i]==0)return 0;
        if(a[i]==0)return -1;
        if(b[i]==0)return 1;
        if(a[i]-b[i]>0)return 1;
        if(a[i]-b[i]<0)return -1;
    }
    return 0;
}
cs

만들어보면 위와 같습니다. 인자는 문자열을 받고 각각의 데이터가 같이 않는동안 for loop를 돌게 됩니다.


문자열 복사도 아래와 같이 만들었습니다.

1
2
3
4
5
6
7
8
void cpy(char *dst,char *src)
{
    int i;
    for(i=0;;i++){
        dst[i] = src[i];
        if(dst[i]==0)break;
    }
}
cs


전체 완성된 코드는 아래와 같습니다.

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
 
#include <stdio.h>
 
#define N_MAX 10
 
char data[N_MAX][80]={
    "hello","abc","a","cdef","cdef","zzzz","bbb","ba","bc","ab"
    };
 
int diff(char *a,char *b){
    int i;
    for(i=0;;i++){
        if(a[i]==0 && b[i]==0)return 0;
        if(a[i]==0)return -1;
        if(b[i]==0)return 1;
        if(a[i]-b[i]>0)return 1;
        if(a[i]-b[i]<0)return -1;
    }
    return 0;
}
void cpy(char *dst,char *src)
{
    int i;
    for(i=0;;i++){
        dst[i] = src[i];
        if(dst[i]==0)break;
    }
}
void swap(int i,int j)
{
    char temp[80];
    cpy(temp,data[i]);
    cpy(data[i],data[j]);
    cpy(data[j],temp);
}
 
void print()
{
    int i;
    for(i=0;i<N_MAX;i++){
        printf("%s\n",data[i]);
    }
}
 
int main()
{
    int i,j;
    for(i=0;i<N_MAX;i++){
        for(j=i+1;j<N_MAX;j++){
            if(diff(data[i],data[j])>0){
                swap(i,j);
            }
        }
    }
    
    print();
    return 0;
}
cs

실행 결과

1
2
3
4
5
6
7
8
9
10
a
ab
abc
ba
bbb
bc
cdef
cdef
hello
zzzz
cs


정수 정렬과 문자열 정렬을 비교해보면, 비교 함수와 swap함수만 제작하면 됩니다.

또 다른 인덱스만 정렬하는것은 다음에 작성하도록 하겠습니다.




댓글 없음:

댓글 쓰기