【问题标题】:Best choice for very simple lookup table非常简单的查找表的最佳选择
【发布时间】:2015-08-29 14:17:11
【问题描述】:

我正在读取一个带有 [a-zA-Z][a-zA-Z0-9] 命令的文件,即两个字符。总共有 43 个不同的命令,我想将这两个字符转换为一个数字 (1..43)。

您将如何进行?我正在考虑创建一个包含 43 个无符号短裤(两个字节)的数组,每个对应于每个命令的两个字符,然后执行以下操作:

//char1: first char of cmd, char2: second char of cmd, lut: array of 43 shorts.
unsigned short tag;
tag = (char1 << 8) | char2;
for(int i=1;i<=43;i++) {
    if(tag==lut[i-1]) return i;
}
return 0;

问题是我不确定这是否是做我想做的最好的方式。我想只有 43 个元素没关系,但这个列表将来可能会增加。

【问题讨论】:

  • 可以使用 hashmap 从命令字符串映射到数字
  • 什么是“LUT”? “查找表”?
  • 这真的取决于你打算用那个数据结构做什么。没有一种完美的数据结构可以满足所有用途。
  • 您可以从这里使用的非常简单和简短的方法开始,如果性能或灵活性成为问题,则可以更改它。
  • 由于内存缓存的影响,假设您需要查看的所有内容都在连续内存中,可以预期一个简单的线性搜索对于数万个元素的性能将优于其他任何方法。此外,对于您的示例,您可能希望使用 int 数据类型来存储您的键值。

标签: c


【解决方案1】:

这是我在旧项目中使用的一种方法。这种方法的一大缺点是查找表和枚举相互依赖,需要保持同步。几年前我从网上的一篇文章中得到这个方法,但不记得在哪里。这是一个完整的例子:

#include <stdio.h>
#include <string.h>

#define CMDSIZE 2

const char* cmd_table[] = { "qu",
                            "qr",
                            "fi",
                            "he"};

enum { CMD_QUIT,
       CMD_QUIT_RESTART,
       CMD_FILE, 
       CMD_HELP,
       CMD_NONE };

int lookup(char command[])
{
  int i = 0;
  int cmdlength = strlen(command);
  for (i = 0; i < cmdlength; i++)
  {
    command[i] = tolower(command[i]);
  }

  const int valid_cmd = sizeof cmd_table / sizeof *cmd_table;

  for (i = 0; i < valid_cmd; i++)
  {
    if (strcmp(command, cmd_table[i]) == 0)
        return i;
  }
  return CMD_NONE;
}

int main()
{
    char key_in[BUFSIZ];
    char command[CMDSIZE+1];
// Wait for command
    do
    {
        printf("Enter command: ");
        fgets(key_in, BUFSIZ, stdin);   
        key_in[strlen(key_in)-1] = '\0';
        strncpy(command, key_in, CMDSIZE);
        command[CMDSIZE] = '\0';
        switch (lookup(command))
        {
            case CMD_QUIT:
        printf ("quit\n");
                break;
            case CMD_QUIT_RESTART:
                printf ("quit & restart\n");
                break;
            case CMD_FILE:
                printf ("file\n");
                break;
            case CMD_HELP:
                printf("help\n");
                break;
            case CMD_NONE:
                if(strcmp(key_in, ""))
                    printf("\"%s\" is not a valid command\n", key_in);
                break;
        }
    } while (strcmp(command, "qu"));
  return 0;
}

编辑:

我找到了我提到的文章:

https://www.daniweb.com/software-development/cpp/threads/65343/lookup-tables-how-to-perform-a-switch-using-a-string

【讨论】:

    猜你喜欢
    • 2021-10-12
    • 1970-01-01
    • 2018-04-03
    • 2023-01-20
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多