ExamRank02_review
1️⃣ 첫번째 문제
(1) 문제
문장이 두개가 아닐시에 '\n'(줄바꿈)문자만 출력하시오.
(2) 문제풀이
#include <unistd.h>
#define TRUE (1)
#define FALSE (-1)
int ft_strlen(char *str)
{
int len;
len = 0;
while (*str++ != '\0')
len++;
return (len);
}
int find_word(char c, char *str, int cnt)
{
while (*str != '\0' && cnt > 0)
{
if (c == *str)
return (TRUE);
str++;
cnt--;
}
return (FALSE);
}
int main(int argc, char *argv[])
{
char *s1;
char *s2;
int cnt;
if (argc == 3)
{
s1 = argv[1];
s2 = argv[2];
cnt = 0;
while (*s1 != '\0')
{
if (find_word(*s1, s2, ft_strlen(s2)) == TRUE && find_word(*s1, s1 - cnt, cnt) == FALSE)
write(1, s1, 1);
s1++;
cnt++;
}
}
write(1, "\n", 1);
}
- 결과값 출력은 원하는 데로 잘나왔습니다. 하지만 오답으로 처리됐습니다.
- 아마도 제가 구현한
int find_word(char c, char *str, int cnt)
함수는 세번째 인자로 검사할범위의 크기를 인자로 받는데 다음의 이유때문에시간초과
가 난 것 같습니다.- 본함수의 while문안에서
find_word(*s1, s2, ft_strlen(s2))
로 작성하면서 반복문을 돌때마다s2
의 길이를 계속해서 확인 - 두번째 조건에서 중복문자체크를 할때 s1문자열을 반복적으로 훝어봄
- 본함수의 while문안에서
- 그래서
char *temp
를 선언하여 중복문자를 담도록하고 처리하도록 하고 쓸데없는 반복이 없도록 처리하였습니다.while (*s1 != '\0') { if (find_word(*s1, s2) == TRUE && find_word(*s1, temp) == FALSE) { write(1, s1, 1); temp[cnt] = *s1; cnt++; } s1++; }
- 이렇게 바꿔주니 정답처리가 잘 되었습니다.
write
함수를 호출할때마다 시간이 걸리기 때문에 다음과 같이 처리하면 좀 더 빠를 것 같습니다.
write(1, temp, cnt + 1);
1️⃣ 두번째 문제
(1) 문제
get_next_line
문제가 나오길 기대했지만 아쉽게도ft_printf
문제가 나왔습니다.- 그나마 다행인 것은 기존
printf
함수의 기능중 일부만 구현하면 됐습니다.%s, %d, %x
서식자만 구현플래그
옵션 구현x- 오직
.
(정밀도) 옵션만 구현
(2) 문제풀이
- 하지만 시간이 부족해서
%x
서식자를 구현하지 못했고 fail하였습니다. - 아무리 일부분만 구현한다고해도
ft_printf
함수를 짧은시간에 구현하는 것은 쉽지 않았습니다. 그나마 다행인 것은 시험에서는norminette
(규칙)을 무시해도 된다는 것 입니다. (norm규칙중에서 함수당 28줄 제한규칙이 까다로움)
< ft_printf.h >
#ifndef FT_PRINTF_H
# define FT_PRINTF_H
# include <stdarg.h>
# include <unistd.h>
# define TRUE (1)
# define FALSE (-1)
typedef struct tool_s {
int point;
int front;
int back;
char result[32];
} tool_t;
#endif
< ft_printf.c >
#include "ft_printf.h"
void *ft_memset(void *str, int value, int size)
{
unsigned char *sp;
sp = str;
while (size-- > 0)
{
*sp = value;
sp++;
}
return (str);
}
int ft_strlen(char *str)
{
int cnt;
cnt = 0;
while (*str++ != '\0')
cnt++;
return (cnt);
}
void ft_itoa(int num, char *num_version, char *str)
{
int num_len;
int cnt;
int nb;
num_len = ft_strlen(num_version);
nb = num / num_len;
cnt = 1;
while (nb > 0)
{
nb /= num_len;
cnt++;
}
str[cnt] = '\0';
while (cnt > 0)
{
str[cnt - 1] = num_version[num % num_len];
cnt--;
num /= num_len;
}
}
int check_word(char c, char *str)
{
while (*str != '\0')
{
if (c == *str)
return (TRUE);
str++;
}
return (FALSE);
}
void set_precision(const char **format, tool_t *fg, va_list ap)
{
while (check_word(**format, "0123456789.") == TRUE)
{
if (**format == '.')
fg->point = 1;
else if (fg->point == 0)
fg->front = fg->front * 10 + **format - '0';
else
fg->back = fg->back * 10 + **format - '0';
(*format)++;
}
}
void print_xd(char c, tool_t *fg, va_list ap, int *len)
{
int result_len;
int bigger;
if (c == 'd')
ft_itoa(va_arg(ap, int), "0123456789", fg->result);
else if (c == 'x')
ft_itoa(va_arg(ap, int), "0123456789abcdef", fg->result);
result_len = ft_strlen(fg->result);\
bigger = result_len > fg->back ? result_len : fg->back;
fg->back = fg->back - result_len;
while (fg->front - bigger > 0)
{
write(1, " ", 1);
(*len)++;
fg->front--;
}
while (fg->back > 0)
{
write(1, "0", 1);
(*len)++;
fg->back--;
}
write(1, fg->result, result_len);
(*len) += result_len;
}
void print_s(tool_t *fg, va_list ap, int *len)
{
int result_len;
char *result;
result = va_arg(ap, char*);
result_len = ft_strlen(result);
if (fg->point == 1 && fg->back < result_len)
result_len = fg->back;
while (fg->front - result_len > 0)
{
write(1, " ", 1);
(*len)++;
fg->front--;
}
write(1, result, result_len);
(*len) += result_len;
}
void set_format(const char **format, va_list ap, int *len)
{
tool_t fg;
ft_memset(&fg, 0, sizeof(fg));
set_precision(format, &fg, ap);
if (**format == 'd')
print_xd('d', &fg, ap, len);
else if (**format == 'x')
print_xd('x', &fg, ap, len);
else if (**format == 's')
print_s(&fg, ap, len);
(*format)++;
}
int ft_printf(const char *format, ...)
{
va_list ap;
int len;
len = 0;
va_start(ap, format);
{
while (*format != '\0')
{
if (*format == '%')
{
format++;
set_format(&format, ap, &len);
}
else
{
write(1, format, 1);
len++;
format++;
}
}
}
va_end(ap);
return (len);
}
(3) fail에 대한 고찰
- 시험은 총 2문제로 두번째문제를 풀지 못하여 시험에 통과하지 못했습니다.(21년 4월 29일 기준)
- 그 이유에대해서는 (개인적)
- 첫번째 문제에서
런타임오류(시간초과) 를 고려하지 않고 해결법을 고민하느라 시간이 많이 소모됨 - 두번째 문제에서 %d(10진수정수), %x(16진수정수) 서식자의 출력코드는 상당부분이 비슷한데 시간이 촉박해서 코드에 대한 큰 틀을 잡지않고 즉흥적으로 구현함
정밀도옵션(.) 에 대한 지식이 정확하지않아 기존의printf
함수로 테스트를 해가면서 구현하느라 시간이 많이 소모됨- 실수로 오타나거나 문법적으로 실수한 부분때문에 디버깅으로 시간이 많이 소모됨
- 첫번째 문제에서
- 고쳐야될점 (개인적)
- 단순히 출력이되는 코드를 구현하는 것이 아닌 효율(속도)를 최대로 높힐 수 있는 코드를 짤 수 있도록 고민해야될 것 같습니다.
ft_printf
와 같이 다소 긴함수는 무작정 코드를 작성하기 보다 먼저코드의 큰 그림 을 구성하고 작성해야겠습니다.- 처음에 코드를 작성할 때부터 문법의 오류나 실수가 나지않도록 연습을 많이해야될 것 같습니다.