[6] C review < 전화번호부 알고리즘 version3.0 >Language/자료구조2021. 11. 22. 17:13
Table of Contents
동작 방식 : 앞서 했던 알고리즘은 배열의 크기를 미리 할당한 후 사용하였습니다. 만약 배열의 크기가 더 커질 필요가 있을때 이 알고리즘은 제대로 동작하지 못합니다. 즉, 배열을 미리 선언할때 동적할당을 하여 선언합니다.
또한 명령어,이름,번호 3가지 모두 한줄에 입력하여 사용할 수 있게 수정합니다.
생각해야될 점 2가지 !
1. 어떻게 동적할당 할 것인가 ?
> malloc을 사용합니다.
2. 명령어 이름 번호를 어떻게 한줄에 입력하여 사용할 것인가 즉, 어떻게 구분 할 것인가 ?
> 명령어 (공백) 이름 (공백) 번호 식으로 공백으로 각 명령어와 입력 인자를 구분합니다.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#define CAPACITY 100
#define BUFFER_SIZE 20
#define INIT_CAPACITY 3
char **names;
char **numbers;
int capacity = INIT_CAPACITY;
int n = 0;
char *delim = " ";
void init_directory();
void process_command();
int read_line(char *str, int limit);
void add(char *name, char *number);
void find(char *name);
void delete (char *name);
void status();
void load(char *fileName);
void save(char *fileName);
int search(char *name);
void reallocate();
int main()
{
init_directory();
process_command();
return 0;
}
void init_directory()
{
names = (char **)malloc(INIT_CAPACITY * sizeof(char *));
numbers = (char **)malloc(INIT_CAPACITY * sizeof(char *));
}
void process_command()
{
char command_line[BUFFER_SIZE];
char *command, *argument1, *argument2;
while (1)
{
printf("$ ");
if (read_line(command_line, BUFFER_SIZE) <= 0)
{
continue;
}
command = strtok(command_line, delim);
if (strcmp(command, "read") == 0)
{
argument1 = strtok(NULL, delim);
if (argument1 == NULL)
{
printf("File name required.\n");
continue;
}
load(argument1);
}
else if (strcmp(command, "add") == 0)
{
argument1 = strtok(NULL, delim);
argument2 = strtok(NULL, delim);
if (argument1 == NULL || argument2 == NULL)
{
printf("Invalid argeuments\n");
continue;
}
add(argument1, argument2);
printf("%s was added successfully\n", argument1);
}
else if (strcmp(command, "find") == 0)
{
argument1 = strtok(NULL, delim);
if (argument1 == NULL)
{
printf("Invalied arguments.\n");
continue;
}
find(argument1);
}
else if (strcmp(command, "status") == 0)
{
status();
}
else if (strcmp(command, "delete") == 0)
{
argument1 = strtok(NULL, delim);
if (argument1 == NULL)
{
printf("Invalid arguments.\n");
continue;
}
delete (argument1);
}
else if (strcmp(command, "save") == 0)
{
argument1 = strtok(NULL, delim);
argument2 = strtok(NULL, delim);
if (argument1 == NULL || strcmp("as", argument1) != 0)
{
printf("Invalid command format\n");
continue;
}
save(argument1);
}
else if (strcmp(command, "exit") == 0)
break;
}
}
int read_line(char *str, int limit)
{
int ch, i = 0;
while ((ch = getchar()) != '\n')
{
if (i < limit - 1)
{
str[i++] = ch;
}
}
str[i] = '\0';
return i;
}
int search(char *name)
{
int i;
for (i = 0; i < n; i++)
{
if (strcmp(names[i], name) == 0)
{
return i;
}
}
return -1;
}
void reallocate()
{
int i;
capacity *= 2;
char **tmp1 = (char **)malloc(capacity * sizeof(char *));
char **tmp2 = (char **)malloc(capacity * sizeof(char *));
for (i = 0; i < n; i++)
{
tmp1[i] = names[i];
tmp2[i] = numbers[i];
}
free(names);
free(numbers);
names = tmp1;
numbers = tmp2;
}
void add(char *name, char *number)
{
if (n >= capacity)
{
reallocate(); // 배열 꽉찬 경우 재할당.
}
int i = n - 1;
while (i >= 0 && strcmp(names[i], name) > 0)
{
names[i + 1] = names[i];
numbers[i + 1] = numbers[i];
i--;
}
names[i + 1] = strdup(name);
numbers[i + 1] = strdup(number);
n++;
}
void find(char *name)
{
int index = search(name);
if (index == -1)
{
printf("찾는 사람이 없습니다.");
}
else
printf("%s\n", numbers[index]);
}
void status()
{
for (int i = 0; i < n; i++)
{
printf("%s %s\n", names[i], numbers[i]);
}
printf("Total person : %d\n", n);
}
void delete (char *name)
{
int index = search(name);
if (index == -1)
{
printf("찾는 사람이 없습니다.");
return;
}
int j = index;
for (; j < n - 1; j++)
{
names[j] = names[j + 1];
numbers[j] = numbers[j + 1];
}
n--;
printf("%s가 정상적으로 삭제 되었습니다.", name);
}
void load(char *fileName)
{
char buf1[BUFFER_SIZE];
char buf2[BUFFER_SIZE];
scanf("%s", fileName);
FILE *fp = fopen(fileName, "r");
if (fp == NULL)
{
printf("Open failed.\n");
return;
}
while ((fscanf(fp, "%s", buf1) != EOF))
{
fscanf(fp, "%s", buf2);
add(buf1, buf2);
n++;
}
fclose(fp);
}
void save(char *fileName)
{
int i;
FILE *fp = fopen(fileName, "w");
if (fp == NULL)
{
printf("Open failed,\n");
return;
}
for (i = 0; i < n; i++)
{
fprintf(fp, "%s %s\n", names[i], numbers[i]);
}
fclose(fp);
}
'Language > 자료구조' 카테고리의 다른 글
[8] C review < 전화번호부 알고리즘 version5.0 preview > (0) | 2021.11.25 |
---|---|
[7] C review < 전화번호부 알고리즘 version4.0 > (0) | 2021.11.23 |
[5] C review < 전화번호부 알고리즘 version2.0 > (0) | 2021.11.22 |
[4] C review < 전화번호부 알고리즘 version1.0 > (0) | 2021.11.22 |
[3] C review < 문자열 응용> (0) | 2021.11.16 |
@Return :: Return
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!