【问题标题】:Open Hashing in C [closed]在 C 中打开散列 [关闭]
【发布时间】:2014-01-31 08:27:58
【问题描述】:
#define maxCells 1000
#define maxCS 11
#define maxIT 19

typedef struct
{
char LN[16], FN[24], MI;
}nametype;

typedef struct studtype
{
unsigned long ID;
nametype name;
char course[8];
int yr;
}student;

typedef struct ctype
{
student stud;
int next;
}celltype;

typedef struct
{
int *Header;
int CourseCtr;  /*holds the # of elements for each course*/
}CSIT;

typedef CSIT Dictionary[2];
typedef int LIST;

typedef struct
{
celltype heap[maxCells];
int AvailPtr;   /*holds the index to the first available cell in the VH*/
}*VirtualHeap;

问题定义:

BSCS 和 BSIT 学生记录的列表存储在使用基于游标的实现表示的内部存储器中。该列表将被转换成一个字典,一个集合 ADT。字典使用开放散列(基于光标)在内存中表示。头表中的每一个组都是按照ID升序排列的。

*Hash 函数存在并且可以在你的函数中调用。该函数将接受一个元素作为其参数,并为每个元素返回适当的哈希值。

编写函数 CreateDic() 的代码——该函数会将 BSCS 和 BSIT 学生记录列表转换为字典,该字典将返回给调用函数。每个学生记录都由 ID 唯一标识。

问题

我不知道问题出在哪里,也不了解任何关于开放散列的信息。我是这种语言的新手。这不是作业,也不是练习。这是我们上周的一次考试,我从来没有想过这个问题。谁能帮我更好地理解这个问题。不管有没有密码。请帮我解决这个问题。

【问题讨论】:

  • 恐怕你将不得不学习一些 C 语言并阅读开放哈希。期望我们在一个 StackOverflow 答案中教你这两件事是不现实的。

标签: c dictionary hash


【解决方案1】:

这可能会给你一个字典的良好开端:

Quick Way to Implement Dictionary in C

如果您是 C 新手,您可能应该在开始使用开放散列之前了解更多有关链表的知识。哈希表的每个条目将包含一个链表,或者至少包含它的头部。

【讨论】:

    【解决方案2】:

    我感觉到你的痛苦。正如其他人所说,在这里可以做些什么来修补您的知识是有限的。这里有几点。

    使用开放散列实现的集合是一个包含 N 个列表头指针的数组(您的老师称此数组为 Header),每个指针都是链表的开头。

    要添加一个新元素,创建并填充一个新的列表单元格,然后根据单元格的键计算一个整数哈希值 H。 (在您的问题中,使用学生 ID 本身作为哈希键可以正常工作。)将新单元格插入到链表中,头指针位于索引处(H mod N)。

    现在,您的老师提供了一个框架,其中我上面提到的“指针”被实现为整数数组索引。他或她设置了一个带有顶部指针(整数索引)的大单元格数组,该指针始终显示已分配单元格的方式。

    这是一个非常规的框架。没有多少生产系统会这样做。编码风格和数据结构选择也是如此,但让我们继续。

    我们需要做一些假设来解决这个问题:1)输入列表是“虚拟堆”的索引,2)我们应该销毁输入列表并重新使用节点来插入哈希集。

    考虑到所有这些,我们可以编写一些代码。

    // Helper to create one CSIT hash set for the given list of students.
    CSIT CreateCSITSet(size_t size, LIST lst, VirtualHeap *vh)
    {
      CSIT csit;
    
      // Allocate the header array of integers and make them null.
      // safe_malloc is just malloc that exits properly if we're out of memory.
      csit.Header = safe_malloc(size * sizeof(int));
    
      // We're using -1 as a null index. 
      for (int i = 0; i < size; i++) csit.Header[i] = -1;
    
      // No students yet inserted.
      csit.CourseCtr = 0;
    
      // Traverse the input list and push onto the hash.
      int next = -1;
      for (int p = lst; p >= 0; p = next) {
    
        // Remember 'next' field because we'll change it below.
        next = vh.heap[p].next
    
        // Use the student ID to find the header index.
        int hix = vh.heap[p].stud.ID % size;
    
        // Push (and also unchain from the input list).
        vh.heap[p].next = csit.Header[hix];
        csit.Header[hix] = p;
    
        // Count the new entry.
        csit.CourseCtr++;
      }
      return csit;  // This returns the entire record: both fields.
    }
    
    // To create the dictionary, call our helper twice to fill in the hash sets.
    Dictionary CreateDic(LIST bscs, LIST bsit, VirtualHeap *vh)
    {
      Dictionary dict = safe_malloc(sizeof(Dictionary));
      dict[0] = CreateCSITSet(maxCS, bscs, vh);
      dict[1] = CreateCSITSet(maxIT, bsit, vh);
      return dict;
    }
    

    这显然未经测试,可能包含小错误,但应该接近。

    请注意,我不满足哈希集中的列表应按排序顺序的要求。我会让你继续努力。

    【讨论】:

      猜你喜欢
      • 2012-07-28
      • 1970-01-01
      • 2022-01-09
      • 2011-08-29
      • 2012-04-16
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多