繁体   English   中英

idiomatic C for int to const string map

[英]idiomatic C for an int to const string map

我怎样才能在C中表达这样的地图?

{
{1, "One"},
{1000, "One thousand"},
{1000000, "One million"}
}

键是一个int,可以是一个大的int,值是一个常量字符串,它在编译时是已知的。

地图将包含大约20或30个元素。

我会写这个函数:

const char* numbers( const int i ) 
{
   switch( i ) {
      case       1: return "One";
      case    1000: return "One thousand";
      case 1000000: return "One million";
      default: return "";
   }
}

这样做有更好的(更惯用的)方式吗?

使用开关完全是惯用的C,无论你是想将键/值数据从程序逻辑中分离出来,都有一个单独的样式考虑(几乎适用于任何语言)。

你可以使用const struct { int key; const char *value; }; const struct { int key; const char *value; }; ,但是你会开始担心你是否应该使用线性搜索,二进制搜索,完美哈希等。使用开关,编译器会将它从你手中夺走。

如果你有一些关联容器(树或hashmap),你在这个项目中用于其他东西,那么你可以使用它,但是不值得为30项集合编写一个。

就像你做的那样:

typedef struct {
    long long key;
    char *val;
} Item;

const Item mydict[] = {
    {1, "One"},
    {1000, "One thousand"},
    {1000000, "One million"}
};

我作为一个练习numbers()函数的主体离开。

Steve Jessop建议的替代解决方案也非常有效。

如果一切都是静态知道的,我会选择这样的东西:

char strings[][] = {"One", "One thousand", "One million", /* whatever */};
int map[] = {1, 1000, 1000000};

const char *numbers(const int i)
{
    position = search(map, i);// if the array is too small, just linear search
                              // if it is big, you can binary search
                              // if there is a relation use a formula
                              // although a formula is not extendable.
                              // In this case, it is log(i) in base 1000.
    return strings[position];
}

该方法可以扩展为非静态数据。 您只需确保正确填充strings数组并保持map排序。

注意:显然,您应该添加足够的错误检查等。例如,在search找不到i的情况下。

这可能是一个解决方案。

基本上创建键值对的排序数组,然后只使用bsearch-function(执行二进制搜索)来快速找到正确的值。 实现自己的二进制搜索以使搜索更方便可能是有意义的。

#include <stdlib.h>
#include <stdio.h>

typedef struct mapping
{
    int key;
    char* value;
} Mapping;

int mappingCompare(const void* a, const void* b)
{
    const Mapping* first = (const Mapping*)a;
    const Mapping* second = (const Mapping*)b;
    return second->key - first->key;
}

int main()
{
    Mapping map[3];
    Mapping search;
    Mapping* result;
    map[0].key = 1;
    map[0].value = "One";
    map[1].key = 1000;
    map[1].value = "One thousand";
    map[2].key = 1000000;
    map[2].value = "One million";

    //qsort is only needed if the map is not already in order
    qsort(map, 3, sizeof(Mapping), mappingCompare);

    search.key = 1000;
    result = (Mapping*)bsearch(&search, map, 3, sizeof(Mapping), mappingCompare);
    printf("value for key 1000 is %s\n", result->value);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM