티스토리 뷰
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Trie {
char data[9]; //단어의 길이는 1~8까지다. (널문자 공간 1 비어놓아야 한다)
struct Trie * next;
struct Trie * child;
}Trie;
Trie * insert(Trie * root, char str[]) {
Trie * newNode = malloc(sizeof(Trie));
newNode->next = NULL;
newNode->child = NULL;
strcpy(newNode->data, str);
Trie * p = root->child;
Trie * bp = NULL; // before p
if(p!=NULL) {
//exist?
for(;p!=NULL;p=p->next) {
int tmp = strcmp(str, p->data);
if(tmp == 0) {
free(newNode);
return p;
}
else if(tmp < 0) {
//non exist, and it's small
if(bp == NULL) root->child = newNode;
else bp->next = newNode; //bp -> p bp->newNode->p
newNode->next = p;
return newNode;
}
bp = p;
}
//non exist, and it's most big
bp->next = newNode;
return newNode;
} else {
root->child = newNode;
return newNode;
} return NULL;
}
void find(Trie*root, int depth) {
for(Trie * p = root->child; p!=NULL; p=p->next) {
for(int i=0; i<depth; i++) printf(" ");
printf("%s\n",p->data);
find(p, depth+1);
}
}
int main()
{
int n;
char str[81]={};
Trie * root = (Trie*) malloc(sizeof(Trie));
root->next = NULL;
root->child = NULL;
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%s",str);
Trie * tmp = root;
int start = 0;
for(int j=0; ; ++j) {
if(str[j] == '\\') { //특수 문자이므로 \\ 앞에 \ 을 붙여야 한다
str[j] = '\0';
tmp = insert(tmp, str+start);
start = j+1; //offset
} else if(str[j] == '\0') { //입력받은 문자열이 끝났다.
tmp = insert(tmp, str+start);
break;
}
}
}
find(root, 0);
return 0;
}
풀이 : 트라이
c언어 14725번 개미굴 (백준)
#include #include #include typedef struct Trie { char data[16]; struct Trie * next; struct Trie * child;}Trie;Trie * insert(Trie * root, char str[]) { //Trie 삽입 Trie * newNode = malloc(sizeof(Trie)); //새로운 노드 만들고 newNode->next = NULL; /
h202.tistory.com
위의 문제와 풀이방법은 거의 같습니다.
다른점은 문자열을 입력받은 부분입니다.
14725번에선 공백을 기준으로 단어를 띄어서 줬지만
여기선 \ 이걸로 분리해서 주고 있습니다.
고로 %s로 한 문자열로 입력을 받은 다음
for문을 이용하여 \이 나오는 부분을 \0으로 바꾸고 트라이에 집어 넣고
또 \이 나오면 그 부분을 \0으로 바꿔서 트라이에 넣고
마지막으로 \0 이 나오면 본래 입력받은 문자열이 끝났음을 의미하고 반복문을 종료합니다.
여기서 중요한 점은 str 에 offset을 더해주어야 합니다.
str 자체는 주소값이기 때문에 \ 이 나왔던 부분의 index에 +1을 하면 이것이 offset이 되며
이것을 str에 더해주면 \ 다음 문자부터 시작하는 주소값이 됩니다.
이해가 안된다면 아래 그림을 보면 됩니다.

이렇게 하면 굳이 변수를 하나 또 만들어서, \나 \0기 전까지 문자들을 복사할 필요가 없습니다. 그냥 주소값에 offset만 더해주면 됩니다!!!!
여기서 \을 왜 \0으로 바꿔야 하는지 의문이 들수도 있습니다만,
c언어에선 문자열을 다룰 때 시작주소만 줄 뿐, 끝은 \0으로 판단하기 때문에, 원하는 단어를 다루기 위해선 꼭 \을 \0으로 바꾸어 주어야 합니다.
\0은 널문자 입니다. 값은 0 입니다.
Trie 부분은 개미굴 문제 풀이에 나와 있습니다.
'c언어 > BAEKJOON' 카테고리의 다른 글
c언어 32652번 아카라카 2 (백준) (0) | 2024.11.18 |
---|---|
c언어 5670번 휴대폰 자판 (백준) (0) | 2024.09.29 |
c언어 14725번 개미굴 (백준) (0) | 2024.09.26 |
c언어 18227번 성대나라의 물탱크 (백준) (0) | 2024.09.07 |
c언어 18437번 회사 문화 5 (백준) (0) | 2024.09.06 |
- Total
- Today
- Yesterday
- 기하학
- XOR
- 세그먼트 트리
- DFS
- java
- 정렬
- Lazy Propagation
- DP
- 플로이드
- C언어
- Krustal
- 그래프
- 그리디
- 백준
- union
- find
- 최대공약수
- 덱
- BFS
- Segment Tree
- 누적합
- 스택
- PASCAL
- 1835
- 누적 합
- C++
- 최소 스패닝 트리
- 1835번
- 브루트포스
- 오프라인 쿼리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |