我有一组明确的字符串及其相应的数字:
kill -> 1
live -> 2
half_kill -> 3
dont_live -> 4
列表是30个这样的字符串及其数字映射。
如果用户输入“kill”,我需要返回1,如果他输入“dont_live”,我需要返回4。
我应该如何在c程序中实现这一目标?我正在寻找一种有效的解决方案,因为这项操作需要完成100次。
提前致谢。
答案 0 :(得分:8)
对表格进行排序,并使用标准库函数bsearch执行二进制搜索。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct entry {
char *str;
int n;
};
/* sorted according to str */
struct entry dict[] = {
"dont_live", 4,
"half_kill", 3,
"kill", 1,
"live", 2,
};
int compare(const void *s1, const void *s2)
{
const struct entry *e1 = s1;
const struct entry *e2 = s2;
return strcmp(e1->str, e2->str);
}
int
main (int argc, char *argv[])
{
struct entry *result, key = {argv[1]};
result = bsearch(&key, dict, sizeof(dict)/sizeof(dict[0]),
sizeof dict[0], compare);
if (result)
printf("%d\n", result->n);
return 0;
}
这是运行程序时的结果。
$ ./a.out kill
1
$ ./a.out half_kill
3
$ ./a.out foo
<no output>
PS:我重复使用了sidyll程序的部分内容。我的答案现在应符合CC BY-SA标准:p
答案 1 :(得分:5)
可能的解决方案:
#include <stdio.h>
#include <string.h>
struct entry {
char *str;
int n;
};
struct entry dict[] = {
"kill", 1,
"live", 2,
"half_kill", 3,
"dont_live", 4,
0,0
};
int
number_for_key(char *key)
{
int i = 0;
char *name = dict[i].str;
while (name) {
if (strcmp(name, key) == 0)
return dict[i].n;
name = dict[++i].str;
}
return 0;
}
int
main (int argc, char *argv[])
{
printf("enter your keyword: ");
char s[100]; scanf("%s", s);
printf("the number is: %d\n", number_for_key(s));
return 0;
}
答案 2 :(得分:3)
这是一种方法:
int get_index(char *s)
{
static const char mapping[] = "\1.kill\2.live\3.half_kill\4.dont_live";
char buf[sizeof mapping];
const char *p;
snprintf(buf, sizeof buf, ".%s", s);
p = strstr(mapping, buf);
return p ? p[-1] : 0;
}
.
混乱是kill
作为half_kill
的子字符串。没有这个问题,你可以直接搜索字符串。
答案 3 :(得分:2)
如果它是一个非常短的字符串列表,那么if
的简单块就足够了
if (0 == strcmp(value, "kill")) {
return 1;
}
if (0 == strcmp(value, "live")) {
return 2;
}
...
如果数字接近10,我会开始描述我的应用程序,并考虑一个地图样式结构。
答案 4 :(得分:1)
如果你有一组固定的strimgs,你有两个选择:生成 完美散列 功能(检查gperf或cmph)或创建 trie ,这样您就不必多次检查字符。 编译器通常使用完美的哈希来识别语言关键字,在你的情况下我可能会使用trie,它应该是最快的方式(但没有什么比直接测量更好!)
答案 5 :(得分:0)
真的是瓶颈吗?只有当简单的解决方案证明太慢时,你才应该担心效率。
话虽如此,可能的速度提升首先要检查长度:
If it's 4 characters then it could be "kill" or "live"
If it's 9 characters then it could be "half_kill" or "dont_live"
或检查switch语句中的第一个字符:
switch (string[0]) {
case 'k':
if (strcmp(string, "kill") == 0)
return 1;
return 0;
case 'l':
...
default:
return 0;
}
答案 6 :(得分:0)
使用hashmap / hashtable我认为这将是最好的解决方案。
答案 7 :(得分:0)
可以使用枚举器吗?
int main(void) {
enum outcome { kill=1, live, half_kill, dont_live };
printf("%i\n", kill); //1
printf("%i\n", dont_live); //4
printf("%i\n", half_kill); //3
printf("%i\n", live); //2
return 0;
}
答案 8 :(得分:-3)
创建一个const值列表:
const int kill = 1; const int live = 2; const int half_kill = 3;
等