[자료구조 - C언어] 자료구조 제14강: Music Library Program(4)

2022. 10. 28. 17:41CS/자료구조

728x90

//공부 기록용 포스팅입니다. 틀린 부분이 있을 경우 댓글로 알려주시면 감사합니다! 😎

 

0. 실행 예

  • Data file name? - 프로그램을 실행하면 어떤 데이터 파일을 load 할지 물어본다.
    • 입력 없이 Enter를 치면 데이터 파일로부터 데이터를 읽지 않고 프로그램을 실행
  • status - 저장된 모든 노래의 번호, 가수, 제목, 파일의 경로명을 출력
    • 노래의 번호는 입력 순서대로 번호 할당
    • 출력 시 가수 이름 알파벳 순으로 출력
      • 동일한 가수 이름이면 노래 제목으로 알파벳 순으로 출력
  • add - 가수 이름, 제목, 파일명으로 추가
    • 파일명은 지정하지 않아도 된다.
  • search - 가수 이름과 노래 제목으로 검색
    • 제목 없이 가수 이름만 검색해도 된다.
  • play 4 - 4번 노래를 play
  • remove 6 - 6번 노래를 목록에서 삭제
  • save as my_collection.txt - 목록을 파일에 저장
  • exit - 종료
  • 파일 형식
    가수#노래제목#경로#
    LESSERAFIM#Sour Grapes# #
    • 가수#노래제목#경로# 순서
    • #문자를 필드 간의 구분자
    • 존재하지 않는 항목의 경우 하나의 공백 문자로 표시
      • 모든 라인은 반드시 구분자로 끝난다.

 

1. 자료구조 정의 하기

  • header 파일에 구조체 정의하기 → c 파일에서 header 파일을 include 하기 때문
  • 순환적인 구조체 정의 순서
      • 자기 자신의 구조체를 정의할 때는 typedef struct 이름 대신 원래 struct 이름을 사용해야 한다.
    struct snode{
        //struct SNode *next, *prev; - 오류
        struct snode *next, *prev;
        Song *song;    //SNode는 하나의 Song을 거느리고 있다
    };
//library.h 
//#ifndef ~ #endif 사이

//타입정의는 일반적으로 헤더파일에 정의
//순환적인 순서 -> 구조체를 정의하기 전에 typedef를 먼저
typedef struct song Song;
typedef struct snode SNode;
typedef struct artist Artist;

struct song{
    Artist *artist;
    char *title;
    char *path;
    int index;
};

struct snode{
    struct snode *next, *prev;
    Song *song;    //SNode는 하나의 Song을 거느리고 있다
};

struct artist {
    char *name;
    struct Artist *next;
    SNode *head, *tail;
};

//library.c

#define NUM_CHARS 256    //한 바이트가 가질 수 있는 모든 값(2^8)

//공유하지 않는 다면 소스코드 파일에 정의
//영어 뿐만 아니라 한글까지 표현 && 한 글자로 이니셜 => 256
Artist *artist_directory[NUM_CHARS];

//add하기 전 초기화 -> main에서 호출
void initialize(){
    for(int i=0; i<NUM_CHARS; i++)
        artist_directory[i] = NULL;
}
//library.h

void initialize();
//main.c

int main(){
    initialize();
}

 

2. 전체 코드

//library.c

#include "library.h"

#define NUM_CHARS 256    //한 바이트가 가질 수 있는 모든 값(2^8)

//공유하지 않는 다면 소스코드 파일에 정의
//영어 뿐만 아니라 한글까지 표현 && 한 글자로 이니셜 => 256
Artist *artist_directory[NUM_CHARS];

//add하기 전 초기화 -> main에서 호출
void initialize(){
    for(int i=0; i<NUM_CHARS; i++)
        artist_directory[i] = NULL;
}

Artist *find_artist(char *name){
    //이름의 첫 글자를 배열 인덱스로
    Artist *p = artist_directory[(unsigned char)name[0]];     //인덱스의 첫 번째 artist
    //name[0]: 00000000 ~ 11111111 사이의 값 -> 배열의 인덱스
    //(unsigned char): 8비트의 첫 번째 자리가 1로 시작하는 경우 -> 음수 를 방지하기 위해
    
    //이름은 알파벳순 정렬이기 때문에 strcmp 값이 적을 때까지만 루프를 순환
    // strcmp(p->name, name) != 0 : 조건은 같은 이름을 찾을 때 까지 루프를 순환
    while(p!=NULL && strcmp(p->name, name) < 0)
        p = p->next;
    
    if(p!=NULL && strcmp(p->name, name) == 0)
        return p;
    else
        return NULL;
}

void add_song(char *artist, char *title, char *path){
    //case 1. artist가 artist_directory에 이미 존재 -> song을 추가
    //case 2. 존재하지 않는 경우 -> artist를 추가 -> song 추가
    
    //artist가 존재하는지 부터 검색 - 존재하지 않으면 NULL 리턴
    Artist *ptr_artist = find_artist(artist);
    if(ptr_artist == NULL){
        
    }else{
        
    }
    
}
//library.h

#ifndef LIBRARY_H
#define LIBRARY_H

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

//타입정의는 일반적으로 헤더파일에 정의
//순환적인 순서 -> 구조체를 정의하기 전에 typedef를 먼저
typedef struct song Song;
typedef struct snode SNode;
typedef struct artist Artist;

struct song{
    struct artist *artist;
    char *title;
    char *path;
    int index;
};

struct snode{
    struct SNode *next, *prev;
    Song *song;    //SNode는 하나의 Song을 거느리고 있다
};

struct artist {
    char *name;
    struct artist *next;
    struct SNode *head, *tail;
};

void initialize();
void add_song(char *artist, char *title, char *path);

#endif /* LIBRARY_H */

 

 

 

 


부경대학교 권오흠 교수님의 [c로 배우는 자료구조 및 여러 가지 예제 실습] 강의 정리입니다. 감사합니다.

https://www.youtube.com/watch?time_continue=2326&v=ma01XeXGvBo&feature=emb_title 

 

728x90