打印
[应用相关]

哈希表实现菜单方法

[复制链接]
251|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
小明的同学|  楼主 | 2023-4-26 20:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
哈希表是一种常用的数据结构,可以用于实现菜单功能。哈希表的基本思想是将菜单项名称映射为一个哈希值,然后将哈希值作为下标,将菜单项存储在数组中。哈希表的优点是能够快速定位菜单项,查找的时间复杂度为常数级别,而且具有较好的空间利用率。

哈希表实现菜单的步骤如下:

创建哈希表:创建一个哈希表,用于存储菜单项。哈希表通常是一个固定大小的数组,数组中的每个元素都是一个链表,用于存储哈希值相同的菜单项。

计算哈希值:将菜单项名称转化为哈希值,可以使用一些常用的哈希算法,例如MD5、SHA1等。

存储菜单项:将计算得到的哈希值作为下标,在哈希表中查找对应的链表。如果链表为空,则创建一个节点,并将菜单项存储在节点中;否则,在链表的末尾添加一个节点,存储菜单项。

查找菜单项:将菜单项名称转化为哈希值,使用哈希值在哈希表中查找对应的链表,然后遍历链表,查找菜单项。如果找到菜单项,则返回对应的菜单项;否则,返回菜单不存在的提示信息。

删除菜单项:将菜单项名称转化为哈希值,使用哈希值在哈希表中查找对应的链表,然后遍历链表,查找要删除的菜单项。如果找到菜单项,则删除对应的节点;否则,返回菜单不存在的提示信息。

哈希表实现菜单的优点是能够快速定位菜单项,具有较好的空间利用率,适用于需要快速查找菜单项的场景。缺点是实现较为复杂,需要考虑哈希冲突等问题。此外,哈希表的实现需要一些较为复杂的算法,不适用于初学者。

使用特权

评论回复
沙发
小明的同学|  楼主 | 2023-4-26 20:41 | 只看该作者
#include <stdio.h>
#include <string.h>

#define HASH_TABLE_SIZE 16

typedef struct menu_node {
    char name[32];
    void (*func)(void);
    struct menu_node *next;
} MenuNode;

MenuNode *hash_table[HASH_TABLE_SIZE];

unsigned int hash_func(const char *str) {
    unsigned int hash = 5381;
    while (*str) {
        hash = ((hash << 5) + hash) + (*str++);
    }
    return hash;
}

void menu_add(const char *name, void (*func)(void)) {
    unsigned int hash = hash_func(name) % HASH_TABLE_SIZE;
    MenuNode *node = hash_table[hash];
    while (node != NULL) {
        if (strcmp(node->name, name) == 0) {
            // 菜单项已存在,更新函数指针
            node->func = func;
            return;
        }
        node = node->next;
    }
    // 创建新节点
    node = (MenuNode *)malloc(sizeof(MenuNode));
    strcpy(node->name, name);
    node->func = func;
    node->next = hash_table[hash];
    hash_table[hash] = node;
}

void menu_remove(const char *name) {
    unsigned int hash = hash_func(name) % HASH_TABLE_SIZE;
    MenuNode *node = hash_table[hash];
    MenuNode *prev = NULL;
    while (node != NULL) {
        if (strcmp(node->name, name) == 0) {
            // 找到要删除的节点
            if (prev != NULL) {
                prev->next = node->next;
            } else {
                hash_table[hash] = node->next;
            }
            free(node);
            return;
        }
        prev = node;
        node = node->next;
    }
}

void menu_run(const char *name) {
    unsigned int hash = hash_func(name) % HASH_TABLE_SIZE;
    MenuNode *node = hash_table[hash];
    while (node != NULL) {
        if (strcmp(node->name, name) == 0) {
            // 执行对应的菜单项函数
            node->func();
            return;
        }
        node = node->next;
    }
    printf("菜单项不存在!\n");
}

void menu_func1(void) {
    printf("执行菜单项1\n");
}

void menu_func2(void) {
    printf("执行菜单项2\n");
}

int main() {
    // 添加菜单项
    menu_add("item1", menu_func1);
    menu_add("item2", menu_func2);

    // 运行菜单项
    menu_run("item1");
    menu_run("item2");

    // 删除菜单项
    menu_remove("item2");

    return 0;
}

使用特权

评论回复
板凳
小明的同学|  楼主 | 2023-4-26 20:41 | 只看该作者
在上面的代码中,哈希表的大小为16,使用了简单的哈希算法(djb2)计算哈希值。menu_add函数用于添加菜单项,如果菜单项已存在,则更新函数指针;menu_remove函数用于删除菜单项;menu_run函数用于运行菜单项对应的函数。在示例代码中,添加了两个菜单项并运行了它们,然后删除了

使用特权

评论回复
地板
公羊子丹| | 2024-6-11 07:01 | 只看该作者

主电路那些环路产生的噪声会加到控制信号上

使用特权

评论回复
5
万图| | 2024-6-11 08:04 | 只看该作者

多次检查也会给单片机带来负荷,对功耗不利

使用特权

评论回复
6
Uriah| | 2024-6-11 09:07 | 只看该作者

在GR-SAKURA中,从IO30引脚到IO35引脚接收来自外部的中断信号

使用特权

评论回复
7
帛灿灿| | 2024-6-11 11:03 | 只看该作者

在掌握对象的变化频度时是有效的

使用特权

评论回复
8
Bblythe| | 2024-6-11 12:06 | 只看该作者

中断信号直接从各外部设备通知中断控制器

使用特权

评论回复
9
周半梅| | 2024-6-11 14:02 | 只看该作者

通过交流电源插头从产品中流走

使用特权

评论回复
10
Pulitzer| | 2024-6-11 15:05 | 只看该作者

来自单 片机内部的定时器和GPIO、串行通信设备UART等外设机器的中断被称为外部设备中断

使用特权

评论回复
11
童雨竹| | 2024-6-11 17:01 | 只看该作者

交流电压在发射EMI

使用特权

评论回复
12
Wordsworth| | 2024-6-11 18:04 | 只看该作者

中断产生于单片机内部和外部的各种设备

使用特权

评论回复
13
Clyde011| | 2024-6-11 19:07 | 只看该作者

这样的设定只需在setup()中定义一次便能在整个程序中有效

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

135

主题

1425

帖子

2

粉丝