我有一些关于我需要做的任务的问题。看起来我正在寻找的是获取代码,然而,我想要做的是学习,因为经过数周的搜索信息后我失去了。 I m really new at
C`。
这是作业:
foo.txt
,bar.txt
,foo2.txt
),它们都有不同的字数(我需要使用动态内存)。创建一个要求单词的程序,并告诉您该单词是否在任何文档中(结果是文档的名称)。
示例:
(我想我需要加载3个文件,创建一个哈希表,其中包含文档中每个单词的键值,但也有一些东西告诉你哪个是单词所在的文档)。
我想我需要实施:
Hash Function
HashValue
Hash Table
的{{1}}(但我认为我还应该存储文档索引?)。HashValue
。dynamic allocation
(使用collisions
和Quadratic Probing
)。我一直在搜索hashmaps实现,哈希表,二次探测,字符串的哈希函数......但是我现在的头脑很乱,我现在不应该从哪里开始。
到目前为止我读过:
Algorithm to get a list of all words that are anagrams of all substrings (scrabble)?
Implementing with quadratic probing
Does C have hash/dictionary data structure?
https://gist.github.com/tonious/1377667
http://www.cs.yale.edu/homes/aspnes/pinewiki/C(2f)HashTables.html?highlight=(CategoryAlgorithmNotes)
提前抱歉我的英语。
希望你能帮助我。
感谢。
第一次编辑
Chaining
数据结构,我检查你给我的链接。思考了一个小时后,我尝试了以下方法:
TRIE
typedef struct WordMetadata {
char* Word;
int Documents[5];
int DocumentsCount;
} WordMetadata;
一个函数,用于加载内存3个文档并索引哈希表中的每个单词。
索引上述结构中的单词的函数
使用二次探测搜索特定单词的功能(如果我解决这个问题,我将尝试使用链接...)。
计算单词哈希值的函数(我想我会使用 void InitTable (WordMetadata **Table) {
Table = (WordMetadata**) malloc (sizeof(WordMetadata) * TABLESIZE);
for (int i = 0; i < TABLESIZE; i++) {
Table[i] = (WordMetadata*) NULL;
}
}
或我在http://www.cse.yorku.ca/~oz/hash.html找到的任何一个)但是现在:
djb2
编辑2
我试图实现一些东西,它没有用,但会看看并告诉我出了什么问题(我知道代码是一团糟)
编辑3
这段代码正在编译和运行,但是,有些单词没有找到(可能没有索引我不知道),我正在考虑转移到我在第一条消息中提到的另一个哈希函数。 / p>
程序正确找到每个文本文件中大约85%的单词(每个大约200个单词)。
其他的是ramdom单词,我认为没有正确索引或者我的搜索功能有错误...
这是当前(全功能)代码:
int Hash (char *WordParam) {
for (int i = 0; *WordParam != '\0';) {
i += *WordParam++;
}
return (i % TABLESIZE);}
答案 0 :(得分:1)
我建议您使用TRIE数据结构来存储内存中所有三个文件中的字符串,因为Hash会占用更多空间。 作为第一步,您应该逐个阅读所有三个文件,对于file_i中的每个单词,您应该执行以下操作:
完成构建TRIE后,检查单词是否存在将是O(1)操作。
如果你要使用哈希表,那么:
您的编辑代码2中的问题:
您身边的杰出进展!!!
快速浏览后,我发现了以下问题:
不要使用gets()方法,而是使用fgets()代替:
gets(Line);
以下内容:
fgets(Line,100,stdin); Line[strlen(Line)-1]='\0'; //fgets stores newline as well. so removing newline.
该行:
if ( j < HashTable[j]->DocumentsCount-1){
导致分段错误。我想您想访问
HashTable[i]
:if ( j < HashTable[i]->DocumentsCount-1){
在行中:
HashTable[ActualPosition]->Documents[HashTable[ActualPosition]->DocumentsCount];
你应该分配一些价值。可能是这样的:
HashTable[ActualPosition]->Documents[HashTable[ActualPosition]->DocumentsCount] = DocumentIndex;
Malloc返回void指针。你应该把它投到适当的 之一:
HashTable[ActualPosition] = (TTable*)malloc (sizeof(TTable));
在Hash中创建新节点时,您还应该使用默认值初始化Documents数组:
for(j=0;j<5;j++)HashTable[ActualPosition]->Documents[j]=-1;
找到后,您将从
HashTable
删除所有内容 用户给出的第一个字。可能是你想把那些代码放在外面 while循环。你的while循环
while(1)
没有任何终止条件,你 应该有一个。
一切顺利!!!
答案 1 :(得分:0)
对于学校作业,您可能不需要担心散列。对于第一遍,你可以改为直接线性搜索:
char **
),每个字典文件一个。char *
次字数统计数组,并将其存储在该文件的char **
中。 (如果在文件中找到100个单词,num_words = 100; fooPtr = malloc(sizeof(char *) * num_words);
现在,您的词典有3个数组,可以使用它们直接扫描单词。
当给出一个单词时,设置一个for循环来查看每个文件的char数组。如果输入的单词与当前扫描的字典匹配,则表示您找到了匹配项并应打印结果。扫描完所有词典后,就完成了。
让事情更快的事情:
我这里几乎没有提供任何代码,只是一种方法。试一试。
最后一点 - 即使您决定使用哈希方法或列表或其他内容,您使用数组编写的代码仍然有用。