프로그램을 동작시키기 위해 구현해야 할 기능들이다.
sa
: swap a - a
의 가장 위에 있는 두 요소를 교환한다. (요소가 하나도 없거나 한 개만 있을 때는 아무것도 수행하지 않는다.)sb
: swap b - b
의 가장 위에 있는 두 요소를 교환한다. (요소가 하나도 없거나 한 개만 있을 때는 아무것도 수행하지 않는다.)ss
: sa
와 sb
를 동시에 수행한다.pa
: push a - b
의 가장 위에 있는 요소를 a
의 가장 위에 넣는다. (b
가 비었을 때는 아무것도 수행하지 않는다.)pb
: push b - a
의 가장 위에 있는 요소를 b
의 가장 위에 넣는다. (a
가 비었을 때는 아무것도 수행하지 않는다.)ra
: rotate a - a
의 모든 요소를 1만큼 위로 이동시킨다. 첫 번째 요소는 마지막 요소가 된다.rb
: rotate b - b
의 모든 요소를 1만큼 위로 이동시킨다. 첫 번째 요소는 마지막 요소가 된다.rr
: ra
와 rb
를 동시에 수행한다.rra
: reverse rotate a - a
의 모든 요소를 1만큼 아래로 이동시킨다. 마지막 요소는 첫 번째 요소가 된다.rrb
: reverse rotate b - b
의 모든 요소를 1만큼 아래로 이동시킨다. 마지막 요소는 첫 번째 요소가 된다.rrr
: rra
와 rrb
를 동시에 수행한다.먼저 sa
, sb
, ss
를 구현하기로 했다.
스택에 노드가 두 개 이상 존재할 때만 기능이 동작하고, 하나만 있거나 하나도 없을 때는 아무 것도 실행하지 않으면 된다.
t_node
형의 temp
변수와 top_next
를 선언해서 temp
에는 stack->top
을, top_next
에는 stack->top->next
를 넣고 두 위치를 바꿔서 연결했다.
원래 temp
에 stack->top
만 넣고 적절히 next
와 prev
를 바꿔서 연결하려고 했는데, 계속 헷갈려서 변수를 두 개 선언했다. 결국 top_next
는 한 번밖에 안 쓰긴 했는데 잘 동작하는 것을 확인하고 그걸 없애서 실행해보니까 잘 동작하지 않았다. 이유는? 모릅니다.
main()
을 작성해서 확인해보니까 노드가 두 개 있었을 경우에는 stack->bottom
을 다시 지정해줘야 했다. 그래서 그 조건을 추가했다.
그리고 ss
는 함수에 넣는 인자를 다르게 해서 두 번 실행하면 되는데, 생각해보니 하나의 기능이 동작할 때마다 그 동작을 출력해줘야 한다.
만약 sa
(혹은 sb
)를 하는 함수에서 sa
(혹은 sb
)를 출력해주고 ss
를 하는 함수에서 함수를 두 번 호출한 다음에 ss
를 출력하게 되면, sa
와 sb
와 ss
가 다 출력될 것이다.
그리고 어차피 sa
와 sb
도 함수를 따로 나누지 않았기 때문에 어떤 스택을 swap할 것인지 구별해야 했다.
그래서 생각한 방법이 인자에 flag
를 추가로 넣어주는 것이다.
숫자로 쓰면 헷갈릴 수 있으니까 structures.h 에 매크로 변수를 선언해서 사용하기로 했다.
# define A 1
# define B 2
# define ALL 3
이렇게 작성해서 조건문을 사용해서 sa
나 sb
, 혹은 ss
를 출력하게 했다.
이번에는 pa
, pb
를 구현했다.
스택에 노드가 한 개 이상 존재할 때만 동작하고, 하나도 없을 때는 아무것도 실행하지 않으면 된다.
이전에 작성했던 push_pop()
을 그대로 사용했다.
대신 그 함수 안에 있던, 노드가 한 개 이상인지 확인해서 하나도 없으면 그냥 리턴하는 그 조건문만 밖으로 빼왔다.
flag
를 확인해서 pa
나 pb
를 출력하는 작업이 실행되면 안 되기 때문이다.
ra
, rb
, rr
을 구현했다.
스택에 노드가 두 개 이상 존재할 때만 동작하고, 하나도 없을 때는 아무것도 실행하지 않으면 된다.
stack->top
을 stack->bottom
으로 옮겨주고 연결을 잘 해줘야 했다.
swap에서 했던 것처럼 t_node
형의 temp
와 top_next
변수를 선언해서 temp
에는 stack->top
을, top_next
에는 stack->top->next
를 넣었다.
stack->bottom->next
에 temp
를 연결하고 그 다음에 temp->prev
를 stack->bottom
으로 연결했다.
temp->next
는 NULL
로 설정했다.
그리고 다시 stack->bottom
을 temp
로 설정했다.
이제 stack->top
을 top_next
로 연결하고 그 다음에 stack->top->prev
를 NULL
로 설정했다.
마지막으로 flag
를 확인해서 ra
, rb
혹은 rr
을 출력하게 했다.
rra
, rrb
, rrr
을 구현했다.
역시 스택에 노드가 두 개 이상 존재할 때만 동작하고, 하나도 없을 때는 아무것도 실행하지 않으면 된다.
이번에는 stack->bottom
을 stack->top
으로 옮겨주고 연결을 잘 해줘야 했다.
rotate와 비슷하게 t_node
형의 temp
와 bottom_prev
변수를 선언해서 temp
에는 stack->bottom
을, bottom_prev
에는 stack->bottom->prev
를 넣었다.
stack->top->prev
에 temp
를 연결하고 그 다음에 temp->next
를 stack->top
으로 연결했다.
temp->prev
는 NULL
로 설정했다. 그리고 다시 stack->top
을 temp
로 설정했다.
이제 stack->bottom
을 bottom_prev
로 연결하고 그 다음에 stack->bottom->next
를 NULL
로 설정했다.
마지막으로 flag
를 확인해서 rra
, rrb
혹은 rrr
을 출력하게 했다.
생각해보니 중복된 수가 들어왔을 때 Error를 출력하고 끝내야 하는데 그 처리를 안 했다.
중복된 수가 들어왔는지 확인하는 check_duplicate()
함수를 작성했다.
이 함수는 일단 스택 리스트를 만들고 난 다음에 실행된다.
만약 인자로 10 42 29 +42 이렇게 들어왔다면, 42 와 +42 는 같은 수라서 중복이다.
그런데 문자열 상태에서 ft_strcmp(42, +42)
이런 식으로 검사를 하게 된다면 같지 않다고 리턴될 것이다.
그래서 리스트가 다 만들어진 다음에 앞에서부터 검사했다.
예를 들어, 인자로 1 3 5 3 7 이 들어왔다고 하자. 먼저 맨 앞의 1 부터 검사한다.
t_node
형의 temp
변수를 선언해서 여기에는 a->next
를 담아준다.(처음에는 스택 a
에만 리스트가 생성되어서 스택 a
만 검사하면 되니까 이름을 a
라고 함)
int
형 cur_value
에는 a->value
가 담긴다. 현재 cur_value
는 1 이다.
그리고 temp
를 끝까지 넘기면서 cur_value
와 같은 수가 있는지 검사한다.
중복되는 숫자가 없으므로 a
를 a->next
로 바꿔준다.
이제 두 번째 인자로 들어온 3 을 검사한다. cur_value
는 3 이다.
temp
는 다시 a->next
가 되고, temp
를 끝까지 넘기면서 cur_value
와 같은 수가 있는지 검사한다.
이번에는 중복된 숫자가 존재하므로 print_error()
를 호출해서 Error 메세지를 출력하고 프로그램을 종료한다.
리스트의 노드들 연결을 이렇게 저렇게 바꾸는 게 헷갈리고 어려울 것 같았는데 생각보다 금방했다.
헷갈리긴 했는데,, 이렇게 하는 게 좋은 방법인지도 잘 모르겠는데,, 일단은 되니까,,
이제 알고리즘 짜야 한다. 으