我不会详细介绍,但我尝试实现类似于Boyer-Moore-Horspool algorithm的算法,只使用十六进制颜色值而不是字符(即,范围更大)。
按照维基百科上的例子,我最初有这个:
size_t jump_table[0xFFFFFF + 1];
memset(jump_table, default_value, sizeof(jump_table);
然而,0xFFFFFF显然是一个巨大的数字,这很快导致C出现seg-fault(但不会出现堆栈溢出,令人失望)。
基本上,我需要的是一个有效的关联数组,将整数映射到整数。我正在考虑使用哈希表,但是为每个条目设置malloc'd结构对我来说似乎有些过分(我也不需要生成哈希值,因为每个键都是唯一的整数,并且不能有重复的条目)。
有没有人有任何建议的替代方案?我对此过于务实吗?
对于那些感兴趣的人,我最终通过uthash库使用哈希表。
答案 0 :(得分:7)
0xffffff
太大而无法放在堆栈上,但你绝对可以malloc
这个大小的缓冲区(至少在当前的计算机上;在智能手机上没有那么多)。是否应该为此任务执行此操作是一个单独的问题。
编辑:根据评论,如果您希望常见案例的条目数量相对较少,而“此颜色不会出现在输入中”跳过值,则应该可能只是继续使用哈希映射(显然只存储实际出现在输入中的值)。
(忽略之前对其他数据结构的讨论,这是基于对正在讨论的算法的错误回忆 - 你想使用哈希表)
答案 1 :(得分:3)
如果你要制作的数组(大小为0xFFFFFF)将是稀疏的,你可以尝试将一个较小的数组作为一个简单的哈希表,其大小为0xFFFFFF / N
,哈希函数为hexValue / N
(或hexValue % (0xFFFFFF / N)
)。你必须要有创意来处理碰撞。
这是我能够预见到malloc
struct
的唯一方法。
答案 2 :(得分:1)
你可以在堆上使用malloc(3)0xFFFFFF块size_t(为简单起见),并像对数组一样解决它们。
堆栈溢出。基本上,程序接收到SIGSEGV,这可能是堆栈溢出或访问非法内存或在只读段上写入等的结果......它们都是在相同的错误消息“Segmentation fault”下抽象的。
但是为什么不使用支持关联数组的更高级语言如python?
答案 3 :(得分:0)
可能以某种速度为代价,你可以尝试修改算法,只找到与某个边界对齐的匹配(每三个或四个符号),然后在字节级执行搜索。
答案 4 :(得分:0)
您可以创建一个稀疏的排序数组,其中包含“页面”(此示例使用256“页面”,因此最上面的字节是页码):
int *pages[256];
/* call this first to make sure all of the pages start out NULL! */
void init_pages(void) {
for(i = 0; i < 256; ++i) {
pages[i] = NULL;
}
}
int get_value(int index) {
if(pages[index / 0x10000] == NULL) {
pages[index / 0x10000] = calloc(0x10000, 1); /* calloc so it will zero it out */
}
return pages[index / 0x10000][index % 0x10000];
}
void set_value(int index, int value) {
if(pages[index / 0x10000] == NULL) {
pages[index / 0x10000] = calloc(0x10000, 1); /* calloc so it will zero it out */
}
pages[index / 0x10000][index % 0x10000] = value;
}
这将在第一次触摸,读取或写入时分配页面。
答案 5 :(得分:0)
为了避免malloc的开销,你可以使用一个哈希表,其中表中的条目是你的结构,假设它们很小。在你的情况下,一对整数应该足够了,有一个特殊的值来表示表中插槽的空白。
答案 6 :(得分:0)
输出空间中有多少个值,即您在0-0xFFFFF范围内映射的不同值的数量是多少?
使用randomized universal hashing,你可以得到一个无冲突的哈希函数,其表格不大于输出空间中值的2倍(对于静态表)