[英]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.