42 Seoul

[42Seoul] libft (part . bonus)

jaewpark 2021. 5. 11. 01:18
typedef struct  s_list
{
    void           *content;
    struct s_list  *next;
}                t_list;

구조체를 주어지고, 이를 이용해서 함수를 작성해야 한다.

content : 요소에 포함된 데이터. void 포인터는 어떠한 종류의 자료형이든 저장할 수 있습니다.

next : 마지막 요소인 경우에는 NULL. 또는 다음 요소의 주소.

 

t_list *ft_lstnew(void *content);

t_list	*ft_lstnew(void *content)
{
	t_list	*new;

	if (!(new = (t_list*)malloc(sizeof(t_list))))
		return (NULL);
	new->content = content;
	new->next = NULL;
	return (new);
}

malloc(3)을 할당하고 새로운 요소를 반환. 변수 'content'는 매개변수 'content'의 값에 따라 초기화된다. 변수 'next'는 NULL로 초기화된다.

 

void ft_lstadd_front(t_list **lst, t_list *new);

void	ft_lstadd_front(t_list **lst, t_list *new)
{
	if (!lst || !new)
		return ;
	new->next = *lst;
	*lst = new;
}

리스트의 시작부분에 요소 'new'를 추가

 

t_list *ft_lstlast(t_list *lst)

t_list	*ft_lstlast(t_list *lst)
{
	if (!lst)
		return (NULL);
	while (lst->next)
		lst = lst->next;
	return (lst);
}

리스트의 마지막 요소를 반환.

 

void ft_lstadd_back(t_list **lst, t_list *new)

void	ft_lstadd_back(t_list **lst, t_list *new)
{
	t_list	*back;

	if (!lst || !new)
		return ;
	if (!*lst)
	{
		*lst = new;
		return ;
	}
	back = ft_lstlast(*lst);
	back->next = new;
}

리스트의 끝에 'new' 요소를 추가.

※기존의 코드에서는 new->next 까지 생각을 했지만, 너무 많이 생각을 한 거 같다.

여기서 원하는 new 요소만 추가를 하니 테스트에서 통과

 

void ft_lstdelone(t_list *lst, void (*del)(void *));

void	ft_lstdelone(t_list *lst, void (*del)(void *))
{
	if (!lst || !del)
		return ;
	del(lst->content);
	free(lst);
}

매개변수로 요소를 가져오고 매개변수로 주어진 함수 'del'을 적용시켜 요소의 content의 주소를 free하고 난 뒤 요소를 free. 'next'의 주소는 free되지 않아야함.

 

void ft_lstclear(t_list **lst, void (*del)(void *));

void	ft_lstclear(t_list **lst, void (*del)(void *))
{
	t_list *tmp;
	t_list *curr;

	curr = *lst;
	if (!lst || !del)
		return ;
	while (curr)
	{
		tmp = curr->next;
		ft_lstdelone(curr, del);
		curr = tmp;
	}
	*lst = NULL;
}

함수 'del'과 free(3)을 사용하여, 주어진 요소와 해당 요소의 모든 후속 요소를 삭제하고 free함.

 

void ft_lstiter(t_list *lst, void (*f)(void *));

void	ft_lstiter(t_list *lst, void (*f)(void *))
{
	if (!lst || !f)
		return ;
	while (lst)
	{
		f(lst->content);
		lst = lst->next;
	}
}

리스트 'lst'를 반복하여 각 요소의 content에 함수 'f'를 적용시킴.

 

t_list *ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *));

t_list	*ft_lstmap(t_list *lst, void *(*f)(void *), void (*del)(void *))
{
	t_list	*ptr;
	t_list	*tmp;

	if (!f || !lst)
		return (NULL);
	ptr = NULL;
	while (lst)
	{
		tmp = ft_lstnew((*f)(lst->content));
		if (!tmp)
		{
			ft_lstclear(&ptr, del);
			return (NULL);
		}
		ft_lstadd_back(&ptr, tmp);
		tmp = tmp->next;
		lst = lst->next;
	}
	return (ptr);
}

리스트 'lst'를 반복하여 각 요소의 content에 함수 'f'를 적용. 함수 'f'를 연속적으로 적용시켜 새로운 리스트를 만듬. 필요한 경우 함수 'del'은 요소의 content를 삭제하는데 사용됨.