#1. 프로시험에 유용한 - 동적할당 대신 사용할수 있는 배열
#3. 프로시험에 유용한 - 트리 사용법 (자연수 ID 를 가지는 트리)
==============================================
지난 번 "동적할당 대신 사용할수 있는 배열" 에 이어지는 것입니다.
역시 한번 살펴보시고 맘에 드시는 분들 참고하시면 됩니다.
hash에서 가장 중요한 Hash key 를 만들어 주는 함수는 시험중에 참고할 수 있는 S/W Problem Solving Reference 에 이미 있습니다.
복사해온 함수의 내용을 보면 복잡하지만 string 을 주면 적당한 key를 만들어 주고 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | unsigned long myhash(const char *str) { unsigned long hash = 5381; int c; while (c = *str++) { hash = (((hash << 5) + hash) + c) % MAX_TABLE; } return hash % MAX_TABLE; } | cs |
사용할 hash table 은 지난번의 single linked list 를 배열로 만든 것입니다.
당연히 다 아시는 개념이겠지만, single linked list 가 여러개 있다고 생각하시면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | struct NODE { char data[7]; NODE * prev; //싱글 리스트를 위해 추가. } a[20000]; //지난번과 동일하게 데이터 저장을 위한 힙입니다. NODE *hTable[MAX_TABLE]; //Hash Table 입니다. | cs |
저장할 데이터를 참고로 적당한 key를 뽑아서 hTable[ key ] 인 single linked list에 저장하는 방식입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 | int key; char in[7] = "aaaaaa'; key = (int)myhash(in); p = myalloc(); strncpy(p->data, in, 7); p->prev = hTable[key]; hTable[key] = p; | cs |
single linked list 와 비교해서 바뀐 내용은 저장을 pList 가 아닌 hTable[key] 에 한다는 점과
이전에는 저장되는 데이터가 int 였으나, 지금은 6자리의 문자열이라는 점 입니다.
마지막으로
Hash table 에서 검색하는 경우는
- 검색 문자열에서 Hash key 생성
- Hash table [key] 에서 검색
하시면 됩니다.
1 2 3 4 5 6 7 8 9 10 11 12 | char search[7] = "vrvipy"; int k = (int)myhash(search); for (NODE * pp = hTable[k]; pp != NULL; pp = pp->prev) { if (!strncmp(search, pp->data, 6)) cout << "FOUND : " << pp->data << endl << endl; } | cs |
Test case 마다 초기화 하실때는 arr_idx 와 Hash table 을 모두 초기화하셔야 합니다
1 | arr_idx = 0; for(int i = 0; i < MAX_TABLE; i++) hTable[i] = nullptr; | cs |
********************
추가로 삭제에 관한 사항입니다.
Sinlgle linked list, Hash 는 삭제를 고려하여 만들어진 것이 아니라 삭제코드는 좀 어렵습니다,
참고만 하시기 바라며,
삭제가 반드시 필요한 경우에는 dummy tail 을 넣어서 삭제하는 방법을 쓰시는 것이 더 편합니다.
(#6. 더블 링크드 리스트의 삭제를 참고하시기 바랍니다)
아래는 전통적인 삭제 코드입니다.
삭제는 해시키를 계산한 후,
hTable[key] 에서 삭제할 데이터를 검색, 검색된 노드의 이전 노드의 prev에 검색된 노드의 prev를 넣어주면 됩니다.
Single linked list 는 이전 노드를 찾아 갈 수 없으므로,
이전 노드의 prev 를 저장해야 하는 어려움이 있습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | char search[7] = "vrvipy"; int k = (int)myhash(search); NODE **del = &hTable[k]; //이전 노드의 위치를 저장할 포인터 변수 for (NODE * iter = hTable[k]; iter != nullptr; iter = iter->prev) //hTable[k]에서 모두 검색 { if (!strncmp(search, iter->data, 6)) { //삭제할 데이터를 찾으면 cout << "FOUND & DEL : " << iter->data << endl << endl; *del = iter->prev; //검색된 노드의 prev를 이전 노드 prev에 저장 } del = &iter->prev; //저장할 이전 노드 prev 위치를 변경 } | cs |
감사합니다.
* key를 만드는 데이터가 String 이 아니더라도 약간의 변경으로 적용이 가능하며,
* 이름, 부서, 전화번호 등등 여러 데이터를 모두 NODE 구조체에 넣고 이중 하나로 Hash key 로 사용하는 방법도 많이 사용됩니다.
main.cpp |
|||
|
input.txt |
100 phqghu meayln lfdxfi rcvscx ggbwkf nqduxw fnfozv srtkjp repggx rpnrvy stmwcy syycqp evikef fmznim kkasvw srenzk ycxfxt lsgyps fadpoo efxzbc oejuvp vaboyg poeylf pbnplj vrvipy amyehw qnqrqp mxujjl oovaow uxwhms ncbxco ksfzkv atxdkn lyjyhf ixjswn kkufnu xxzrzb mnmgqo oketly hnkoau gzqrcd diutei ojwayy zpvscm psajlf vgubfa aovlzy lntrkd cpwsrt esjwhd izcobz cnfwlq ijtvdw vxhrcb ldvgyl wgbusb mborxt lhcsmp xohgmg nkeufd xotogb gxpeya nfetcu kepzsh kljugg gekjdq zjenpe vqgxie pjsrdz jazujl lchhbf qmkimw zobiwy bxduun fsksrs rtekmq dcyzje euhmsr qcozij ipfion eeddps zrnavy mmtatb dzqsoe muvnpp psuacb azuxmh ecthle grpunk dmbppw eqtgjo parmow zdqyox ytjbbh awdydc prjbxp hoohpk wqyuhr qzhnbn fuvqnq
|
|
1. mymest, mystrcpy, mystrcmp 구현 함수 알기 2. stdio.h 에서 돌아가는 것 확인하기 |
'Computer Science' 카테고리의 다른 글
4 트리 사용법 (0) | 2019.01.17 |
---|---|
트리 사용법(자연수 아이디를 가지는 트리) (0) | 2019.01.17 |
동적할당 대신 사용할 수 있는 배열 (0) | 2019.01.17 |
2019112 우선순위 큐, 힙, 링크드 리스트 (0) | 2019.01.17 |
queue (0) | 2019.01.17 |
댓글