본문 바로가기
프로그래밍/C

C언어 ] 맵 자료구조 구현

by eteo 2023. 5. 7.

 

 

map 생성시 사이즈를 직접 결정할 수 있도록 해보았다. 근데 링버퍼처럼 범용적으로 쓸 거 같진 않아서 사실 고정길이배열로 mapManger 구조체안에 둬도 될 것 같다.

 

 

 

 

map.h

#include "main.h"

#define MAP_MAX_KEY_LEN		20

// 맵 자료구조
typedef struct
{
	char key[MAP_MAX_KEY_LEN+1];
	uint32_t value;
} map_t;

// 맵 자료구조 관리 구조체
typedef struct
{
	map_t* maps;
	uint32_t currentSize;
	uint32_t maxSize;
} mapManager_t;

void map_create(mapManager_t* mapManager, map_t* maps, uint32_t maxSize);
void map_insert(mapManager_t* mapManager, const char *key, uint32_t value);
void map_delete(mapManager_t* mapManager, const char* key);
void map_printAll(mapManager_t* mapManager);
uint32_t map_search(mapManager_t* mapManager, const char *key);
uint32_t map_getMaxSize(mapManager_t * mapManager);
uint32_t map_getCurrentSize(mapManager_t* mapManager);

 

 

 

 

 

map.c

#include "map.h"

#define printMsg(fmt, ...)	printf(fmt, ##__VA_ARGS__)

// 맵 생성 함수
void map_create(mapManager_t* mapManager, map_t *maps, uint32_t maxSize)
{
	mapManager->maps = maps;
	mapManager->maxSize = maxSize;
	mapManager->currentSize = 0;
}

// 맵에 자료를 추가하는 함수
void map_insert(mapManager_t* mapManager, const char* key, uint32_t value)
{
	if (mapManager->currentSize >= mapManager->maxSize)
	{
		printMsg("Error: Map is full.\n");
		return;
	}

	for (int i = 0; i < mapManager->currentSize; i++)
	{
		if (strcmp(mapManager->maps[i].key, key) == 0)
		{
			printMsg("Error: Duplicated key.\n");
			return;
		}
	}

	if (strlen(key) > MAP_MAX_KEY_LEN)
	{
		printMsg("Error: Too long key.\n");
		return;
	}

	strcpy(mapManager->maps[mapManager->currentSize].key, key);
	mapManager->maps[mapManager->currentSize].value = value;
	mapManager->currentSize++;
}

// 맵에서 자료 삭제하는 함수
void map_delete(mapManager_t* mapManager, const char* key)
{
	int indexToDelete = -1;
	for (int i = 0; i < mapManager->currentSize; i++) {
		if (strcmp(mapManager->maps[i].key, key) == 0) {
			indexToDelete = i;
			break;
		}
	}
	if (indexToDelete == -1) {
		printMsg("Error: Key not found.\n");
		return;
	}

	for (int i = indexToDelete; i < mapManager->currentSize - 1; i++) {
		mapManager->maps[i] = mapManager->maps[i + 1];
	}
	mapManager->currentSize--;
}

// 맵 전체 출력 함수
void map_printAll(mapManager_t* mapManager)
{
	for (int i = 0; i < mapManager->currentSize; i++) {
		printMsg("%s: %u\n", mapManager->maps[i].key, mapManager->maps[i].value);
	}
}

// 맵에서 key로 검색하면 value를 반환하는 함수
uint32_t map_search(mapManager_t* mapManager, const char* key)
{
	for (int i = 0; i < mapManager->currentSize; i++) {
		if (strcmp(mapManager->maps[i].key, key) == 0) {
			return mapManager->maps[i].value;
		}
	}
	printMsg("Error: Key not found.\n");
	return 0xffffffff;
}

// 맵 max size 반환 함수
uint32_t map_getMaxSize(mapManager_t* mapManager)
{
	return mapManager->maxSize;
}

// 맵 current size 반환 함수
uint32_t map_getCurrentSize(mapManager_t* mapManager)
{
	return mapManager->currentSize;
}

 

 

 

 

 

 

 

 

간단하게 테스트 해보기

 

#include "main.h"
#include "map.h"
#define _CRT_SECURE_NO_WARNINGS

void printMenu()
{
    printf("\nMenu :\n");
    printf("1. Insert\n");
    printf("2. Delete\n");
    printf("3. Search\n");
    printf("4. Print All\n");
    printf("5. Quit\n");
}

map_t maps[5];
mapManager_t mapManager;

int main(void)
{
    int command = 0;
    char key[20];
    uint32_t value;

    map_create(&mapManager, maps, 5);

    while (command != 5)
    {
        printMenu();
        scanf("%d", &command);

        switch (command)
        {
        case 1:
            printf("Enter Key: ");
            scanf("%s", key);
            printf("Enter Value: ");
            scanf("%u", &value);
            map_insert(&mapManager, key, value);
            break;
        case 2:
            printf("Enter key to delete: ");
            scanf("%s", key);
            map_delete(&mapManager, key);
            break;
        case 3:
            printf("Enter key to search: ");
            scanf("%s", key);
            printf("Value : %u\n", map_search(&mapManager, key));
            break;
        case 4:
            printf("All maps:\n");
            map_printAll(&mapManager);
            break;
        case 5:
            printf("Exit the program.\n");
            break;
        default:
            printf("Invalid Command.\n");
        }
    }

    return 0;
}