int到const字符串映射的惯用C
我如何用C语言表达像这样的地图int到const字符串映射的惯用C,c,idioms,C,Idioms,我如何用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
{
{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;}代码>,但随后您将开始担心是否应该使用线性搜索、二进制搜索、完美散列等。通过一个开关,编译器将其从您的手中拿走
如果您有某种关联容器(树或hashmap)用于此项目中的其他内容,那么您可以使用它,但为30项集合编写一个容器并不值得。就像您所做的那样:
typedef struct {
long long key;
char *val;
} Item;
const Item mydict[] = {
{1, "One"},
{1000, "One thousand"},
{1000000, "One million"}
};
我将numbers()
函数体作为练习
所建议的替代解决方案也是完全有效的。如果所有问题都是静态已知的,我将采用以下方式:
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];
}
这种方法可以扩展到非静态数据。您只需确保正确填充字符串
数组,并保持映射
排序即可
注意:显然,您应该添加足够的错误检查等。例如,在搜索
无法找到i
的情况下,这可能是一种解决方案
基本上创建排序后的键值对数组,然后使用b搜索函数(执行二进制搜索)快速找到正确的值。实现您自己的二进制搜索以使搜索更加方便可能是有意义的
#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);
}
#包括
#包括
typedef结构映射
{
int键;
字符*值;
}制图;
int-mappingCompare(常量无效*a,常量无效*b)
{
常量映射*第一=(常量映射*)a;
常量映射*秒=(常量映射*)b;
返回第二个->键-第一个->键;
}
int main()
{
地图[3];
地图搜索;
映射*结果;
映射[0]。键=1;
映射[0]。value=“一”;
图[1],键=1000;
图[1]。value=“一千”;
映射[2]。键=1000000;
地图[2]。value=“一百万”;
//仅当地图未按顺序排列时才需要qsort
qsort(映射,3,sizeof(映射),映射比较);
search.key=1000;
结果=(映射*)b搜索(&search,map,3,sizeof(映射),mappingCompare);
printf(“键1000的值为%s\n”,结果->值);
}
这就是哈希表的用途。在C语言中,与其他高级语言不同的是,该语言不提供这样的功能,您必须提出自己的功能。@BlagovestBuyukliev:散列整数有些不寻常。对于数字键,二进制搜索更为常见。(当然可以,但是没有太多的哈希函数在整型数据上进行测试。)@Dietrich:是的,我说的是更一般的意义。仅供参考:人们已经实现了各种C库来解析、访问和输出JSON,如下所示:这是一个怎样的答案?你基本上完全忽略了OP的问题,把它作为一个练习!!你肯定是想返回字符串[位置]?我本来会编辑的,但修改的时间太短了。