Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 有没有更快的方法来查找数据?_C_Algorithm - Fatal编程技术网

C 有没有更快的方法来查找数据?

C 有没有更快的方法来查找数据?,c,algorithm,C,Algorithm,这是一个面试问题 我们正在开发一个k/v系统,其中一部分已经开发完成,我们需要你完成它 已经完成的事情- int set(char *key, char *value); char *get(char *key); 1) 返回任意字符串的散列,您可以假设返回值总是唯一的,没有冲突, 这取决于你是否使用它 int hash(char *string); 你必须完成的事情- int set(char *key, char *value); char *get(char *key); 我的回答是

这是一个面试问题

我们正在开发一个k/v系统,其中一部分已经开发完成,我们需要你完成它

已经完成的事情-

int set(char *key, char *value);
char *get(char *key);
1) 返回任意字符串的散列,您可以假设返回值总是唯一的,没有冲突, 这取决于你是否使用它

int hash(char *string);
你必须完成的事情-

int set(char *key, char *value);
char *get(char *key);
我的回答是

struct kv {
        int key;
        char *value;
        kv *next;
};                  

struct kv *top;
struct kv *end;

void set(char *key, char *value) {
        if(top == NULL) {
                top = malloc(struct kv);
                end = top;
        }       
        sturct kv *i = top;
        int k = hash(key);
        while(i != end) {
                if(i->key == k) {
                        i->value = value;
                        return;
                }
                i = i->next;
        }
        i = malloc(struct kv);
        i->key = k;
        i->value = value;
        end = i;
}       

char *get(char *key) {
        if(top == NULL) {
                return NULL;
        }
        sturct kv *i = top;
        int k = hash(key);
        while(i != end) {
                if(i->key == k) {
                        return i->value;
                }       
                i = i->next;
        }       
        return NULL;
}   

Q:-有没有更快的方法?您认为最快的方法是什么?

您所做的是制作一个链表来存储键值对。但是正如您所看到的,搜索的复杂性是
O(n)
。您可以通过创建哈希表来加快速度。您已经有一个保证0冲突的哈希函数

你能做的就是

char* hash_tables[RANGE_OF_HASH] = {NULL}; // Your interviewer should provide you RANGE_OF_HASH
然后您的
设置
获取
成为-

void set(char* key, char* value) {
    hash_table[hash(key)] = value; // Can do this because no collisions are guaranteed. 
}

char* get(char* key) {
    return hash_table[hash(key)];
}
在这种情况下,由于您不必迭代插入的所有键,因此
get
的复杂性是
O(1)
(也就是
set

但您需要意识到,这通常比您的方法占用更多的空间。 您的方法占用了
O(n)
空间,但这占用了
O(散列的范围)
。这在内存受限的情况下可能是不可接受的

如果哈希表的
范围非常大(如
INT\u MAX
),并且没有足够的内存来存储哈希表,则可以创建多级哈希表

例如,主
hash_表
将只有
256个
插槽。每个条目将指向另一个包含256个条目的哈希表,以此类推。你会有
执行一些位掩蔽以获取每个级别的哈希值。您可以根据需要分配每个级别。这样可以最大限度地减少内存使用。

有很多很好的方法可以做到这一点。这是一个小的阅读清单,请仔细阅读。肯定还有更多我不知道的事情

  • 排序列表-根据使用模式,可以快速或缓慢构建,但查找保证为O(log(N))
  • -快速,平均接近O(1),在所有操作的最坏情况下接近O(N)
  • -最佳情况O(log(N)),最坏情况O(N)。
    • -所有操作的保证O(对数(N))
    • -与AVL类似,但在查找速度和插入速度之间进行了权衡
  • -在所有操作上为真O(1),但以牺牲更多内存使用为代价

在此之后,休息一下,振作起来,深入研究。这已经是很高级的东西了,它会告诉你,有时候一个更糟糕的衡量标准在现实世界中的表现会更好。这完全取决于将有什么样的数据以及使用模式。

您应该查看HashMap/HashTables。它们可能就是您正在寻找的答案。
table[hash(key)]=value
和return
table[hash(key)]
是您要寻找的。您需要处理多少个k/v对。对于大多数系统,答案必须小于2^32,因为您的完美散列函数可能只返回那么多不同的值-但我们谈论的是数百、数千、数百万或数十亿个键吗?这会影响你的工作。如果面试官没有告诉你,你可以问。面试官希望得到合理的问题来澄清规格。您可以检查
int
是否也是32位的量。面试官故意不告诉你所有的事情来了解你要问什么。很抱歉这么说,但你的解决方案在效率方面是最糟糕的。问题1是用“k/v系统”来问他们?这不是一个正式的术语。我猜这意味着键值对。。。但是那些为计算机行业发明更愚蠢缩写的人需要被击倒。没有散列的范围,或者是最大值_INT@yaminunaz
MAX\u INT
散列范围的“OK”值,但
HASH\u表所需的大小将非常高。一般来说,操作系统应该能够提供这么多的内存。因为无论如何,您将使用很少的表条目。只需确保您没有手动初始化为0。但是通过将哈希表声明为全局或静态来使用系统分配的零页。不使用给定的完美哈希值是一种浪费,当然不是面试官期望的答案。@YvesDaoust-可能吧,但是一个同时包含哈希表和其他选项的答案会更令人印象深刻。对我来说不是。这看起来像是在炫耀你的知识而没有辨别力,没有利用问题陈述中给出的信息。没有理由切换到效率较低的解决方案。@YvesDaoust-当然,这取决于上下文。在最初的访谈中,当被要求完成C代码时,很明显他们希望看到一个哈希表,所以就这样做吧。之后,如果你有机会谈论它,你可以提到这些。不管怎样,OP问
有没有更快的方法?你认为最快的方法是什么?
-这就是答案。这与其说是关于这个特定的面试(反正已经结束了),不如说是关于一般知识。你为什么建议慢一点的解决方案?为什么要回答一个你没有被问到的问题?这是缺乏重点。顺便说一句,从技术上讲,预期的解决方案不是哈希表,而是普通数组。