Dev2yup의 프로그래밍 이야기 🖥 💻

C

[18] 백준 1181번 단어 정렬문제 (실패 -> 성공)(수정)

엽동이 2022. 7. 2. 01:58

문제

알파벳 소문자로 이루어진 N개의 단어가 들어오면 아래와 같은 조건에 따라 정렬하는 프로그램을 작성하시오.

  1. 길이가 짧은 것부터
  2. 길이가 같으면 사전 순으로

입력

첫째 줄에 단어의 개수 N이 주어진다. (1 ≤ N ≤ 20,000) 둘째 줄부터 N개의 줄에 걸쳐 알파벳 소문자로 이루어진 단어가 한 줄에 하나씩 주어진다. 주어지는 문자열의 길이는 50을 넘지 않는다.

출력

조건에 따라 정렬하여 단어들을 출력한다. 단, 같은 단어가 여러 번 입력된 경우에는 한 번씩만 출력한다.

예제 입력 1 복사

13
but
i
wont
hesitate
no
more
no
more
it
cannot
wait
im
yours

예제 출력 1 복사

i
im
it
no
but
more
wait
wont
yours
cannot
hesitate

<제출한 코드>

#include <stdio.h>
#include <string.h>

int main(void)
{
    char word[20000][50], tmp[50];
    int wordNum;

    scanf("%d", &wordNum);
    for (int i = 0; i < wordNum; i++){
        scanf("%s", word[i]);
    }
    
    for (int i = 0; i < wordNum; i++){
        for (int j = 0; j < wordNum - 1; j++){
            if (strlen(word[j]) > strlen(word[j + 1])){  // 문자열 길이 오름차순 정렬
                strcpy(tmp, word[j]);
                strcpy(word[j], word[j + 1]);
                strcpy(word[j + 1], tmp);
            }
        }
    }
    
    for (int i = 0; i < wordNum; i++){
        for (int j = 0; j < wordNum - 1; j++){
            if (strlen(word[j]) == strlen(word[j + 1])){  // 문자열 길이가 같을 때 알파벳 순서대로 정렬
                if (strcmp(word[j], word[j + 1]) > 0){
                    strcpy(tmp, word[j]);
                    strcpy(word[j], word[j + 1]);
                    strcpy(word[j + 1], tmp);
                }
            }
        }
    }
    
    for (int j = 0; j < wordNum - 1; j++){
        if (strcmp(word[j], word[j + 1]) == 0){  // 문자열이 중복될 경우 하나 삭제
            strcpy(word[j + 1], "nonono");
        }
    }
    
    for (int i = 0; i < wordNum; i++){
       if (strcmp(word[i], "nonono") != 0) printf("%s\n", word[i]);
    }

    return 0;
}

기능상에는 문제가 없지만 런타임 에러가 발생하여 실패하였다.

인터넷에 검색해본 결과 이 문제는 포인터를 알아야 풀 수 있는 문제인것 같아 보류해두고 나중에 다시 도전하기로 하였다.

 

 

<다시 제출한 코드>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int compare(char *a, char *b)  //qsort compare함수  
{
    int num1 = strlen(a);    
    int num2 = strlen(b);   

    if (num1 < num2)    
        return -1;     
    
    if (num1 > num2)    
        return 1;      
    
    else return strcmp(a,b);
}

int main(void){
    int N;
    char word[20000][51];

    scanf("%d", &N);
    for (int i = 0; i < N; i++){
        scanf("%s", word[i]);
    }
    qsort(word, N, sizeof(char) * 51, compare); // qsort
    printf("%s\n", word[0]); //0번째 인덱스 먼저 출력
    for (int i = 1; i < N; i++){
        if (strcmp(word[i - 1], word[i])) printf("%s\n", word[i]); // 조건문은 0이 아닌 모든 상수를 참 취급
    }
    return 0;
}

 

qsort를 이용하여 문자열 길이순으로 정렬하였다.

 

strcmp(a, b) a, b는 문자열일 때

a > b일 경우 1을 반환, a < b일 경우 -1을 반환, a == b일 경우 0을 반환한다.

 

조건문은 0이 아닌 다른 정수는 모두 참 취급하므로 마지막 조건문에서 word[i - 1]과 word[i]를 비교했을 때 0이 아니라면(중복 단어가 아니라면) 출력하게 된다.

 

https://velog.io/@honeyricecake/%EB%B0%B1%EC%A4%80-1181%EB%B2%88-%EB%8B%A8%EC%96%B4-%EC%A0%95%EB%A0%AC

 

백준 1181번 단어 정렬

https://www.acmicpc.net/problem/1181내 코드처음으로 C언어 내장함수인 qsort를 써보았다.내장 헤더파일은 <stdlib.h>이며사용법은 다음과 같다.qsort(배열의 주소, 요소의 개수, 요소 하나의 크기, 비교함수)

velog.io

위 블로그를 참고했음