문제
상근이는 문자열에 폭발 문자열을 심어 놓았다. 폭발 문자열이 폭발하면 그 문자는 문자열에서 사라지며, 남은 문자열은 합쳐지게 된다.
폭발은 다음과 같은 과정으로 진행된다.
- 문자열이 폭발 문자열을 포함하고 있는 경우에, 모든 폭발 문자열이 폭발하게 된다. 남은 문자열을 순서대로 이어 붙여 새로운 문자열을 만든다.
- 새로 생긴 문자열에 폭발 문자열이 포함되어 있을 수도 있다.
- 폭발은 폭발 문자열이 문자열에 없을 때까지 계속된다.
상근이는 모든 폭발이 끝난 후에 어떤 문자열이 남는지 구해보려고 한다. 남아있는 문자가 없는 경우가 있다. 이때는 "FRULA"를 출력한다.
폭발 문자열은 같은 문자를 두 개 이상 포함하지 않는다.입력
첫째 줄에 문자열이 주어진다. 문자열의 길이는 1보다 크거나 같고, 1,000,000보다 작거나 같다.
둘째 줄에 폭발 문자열이 주어진다. 길이는 1보다 크거나 같고, 36보다 작거나 같다.
두 문자열은 모두 알파벳 소문자와 대문자, 숫자 0, 1, ..., 9로만 이루어져 있다.
출력
첫째 줄에 모든 폭발이 끝난 후 남은 문자열을 출력한다.
문제의 입력 조건에서 문자열의 길이가 최대 1,000,000이라는 것을 보고 입력받은 문자열에서 폭발문자열이 나오지 않을때 까지 무한 루프를 돌아서 해결하는 것은 TLE가 나올 것이라고 생각했다.
(수정 : 무한 루프가 아닌 단순 루프 방법으로도 가능하다)
물론 입력 문자열의 부분문자열 중 폭발 문자열임을 찾아낼 때 반복문이 아닌 string 헤더파일의 strcmp함수를 사용할 수 있겠지만 무한루프의 리스크가 크다.따라서 자료구조 중 stack을 사용했다.
입력 문자열을 stack에 하나씩 넣으면서폭발 문자열의와 stack에 들어갈 문자가 같으면 stack의 마지막 위치인 top에 NULL값을 넣고 폭발 문자열의 길이만큼 뒤로 간 위치의 주소와 폭발 문자열의 주소를 strcmp함수에 보내서 둘을 비교한다. 값이 동일하면 0이 리턴될 것이니 stack에서 폭발 문자열의 길이만큼 값을 pop해준다.마지막 문자
이 과정을 반복하면 폭발 문자열이 모두 제거된 문자열을 얻을 수 있다.
코드의 핵심은 폭발문자열의 마지막 문자를 인식해야하는 것이다.
왜냐하면 첫 자리를 인식하면 한 번 제거하고 만들어진 새로운 문자열에서 첫 번째 문자를 인식하지 못하기 때문이다. (stack은 선입선출이다. 포인터가 1개이기 때문에 이전의 값을 따로 탐색해주어야 한다.)
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
char stack_str[1000005];
char str[1000005];
char bomb_str[38];
int main(void)
{
int top = 0, i, j, bomb_length;
scanf("%s", str);
scanf("%s", bomb_str);
bomb_length = strlen(bomb_str);
for (i = 0; str[i] != '\0'; i++)
{
stack_str[top++] = str[i];
if (bomb_str[bomb_length - 1] == str[i])
{
stack_str[top] = '\0';
if (strcmp(&stack_str[top - bomb_length], bomb_str) == 0)
{
for (j = 0; j < bomb_length; j++)
{
top--;
stack_str[top] = '\0';
}
}
}
}
stack_str[top] = '\0';
if (top == 0)
{
printf("FRULA\n");
}
else
{
printf("%s\n", stack_str);
}
return 0;
}
백준 티어가 낮아서 부끄러워서 이름을 가리는 건 안비밀... 사실 메모리랑 시간, 언어, 코드길이로 알 수도 있겠지만...
strcmp함수를 사용하는 조건문 부분에서 memset함수를 사용해도 된다. top은 bomb_length만큼 감소시키면 된다.