C++ 具有链接列表的哈希表中的前10个频率

C++ 具有链接列表的哈希表中的前10个频率,c++,pointers,loops,hashtable,linked-list,C++,Pointers,Loops,Hashtable,Linked List,下面的代码将在我的哈希表(其中有一组链表)中以最高频率打印我10次。我需要我的代码来打印哈希表中的前10个频率。我不知道如何做到这一点(代码示例会很好,纯英语逻辑/伪代码也一样好) 我创建了一个名为“tmp”的临时哈希列表,它指向我的哈希表“hashtable” 然后,while循环遍历列表并查找最高频率,即int'tmp->freq' 循环将继续使用变量“topfreq”复制找到的最高频率,直到到达哈希表上链接列表的末尾 我的“node”是一个由变量“freq”(int)和“word”(128

下面的代码将在我的哈希表(其中有一组链表)中以最高频率打印我10次。我需要我的代码来打印哈希表中的前10个频率。我不知道如何做到这一点(代码示例会很好,纯英语逻辑/伪代码也一样好)

  • 我创建了一个名为“tmp”的临时哈希列表,它指向我的哈希表“hashtable”
  • 然后,while循环遍历列表并查找最高频率,即int'tmp->freq'
  • 循环将继续使用变量“topfreq”复制找到的最高频率,直到到达哈希表上链接列表的末尾
  • 我的“node”是一个由变量“freq”(int)和“word”(128字符)组成的结构。当循环没有其他要搜索的内容时,它会在屏幕上打印这两个值

    问题是,我不知道如何从刚找到的数字中找到下一个最低的数字(这可能包括另一个具有相同freq值的节点,因此我必须检查单词是否也相同)

    void toptenwords()
    {
    int-topfreq=0;
    int minfreq=0;
    字符首字[SIZEOFWORD];
    对于(int p=0;p<10;p++)//我们需要前10个频率……所以我们做了10次
    {
    for(int m=0;mfreq>topfreq)//如果手头的频率大于找到的频率,则存储。。。
    {
    topfreq=tmp->freq;
    strcpy(topword,tmp->word);
    }
    tmp=tmp->next;
    }
    }
    
    cout我将维护一组已经使用的单词,并更改最内部的if条件,以测试频率是否大于以前的最高频率,以及tmp->word是否不在已经使用的单词列表中。

    在哈希表上(然后在其中包含的每个链接列表上)进行迭代时,保留一个自平衡二叉树(std::set)作为“结果”列表。当您遇到每个频率时,将其插入列表,如果列表中有10个以上的条目,则将其截断。完成后,您将拥有一组前十个频率(排序列表),您可以根据需要对其进行操作


    使用集合而不是哈希表本身中的链表可能会有执行增益,但您可以自己解决。

    保留一个包含10个节点指针的数组,并将每个节点插入数组,保持数组的排序顺序。数组中的第十一个节点在每次迭代时都会被覆盖,并且包含垃圾

    void toptenwords()
    {
            int topfreq = 0;
            int minfreq = 0;
            node *topwords[11];
            int current_topwords = 0;
    
            for(int m = 0; m < HASHTABLESIZE; m++) // Go through the entire hast table
            {
                    node* tmp;
                    tmp = hashtable[m];
    
                    while(tmp != NULL) // Walk through the entire linked list
                    {
                            topwords[current_topwords] = tmp;
                            current_topwords++;
                            for(int i = current_topwords - 1; i > 0; i--)
                            {
                                    if(topwords[i]->freq > topwords[i - 1]->freq)
                                    {
                                            node *temp = topwords[i - 1];
                                            topwords[i - 1] = topwords[i];
                                            topwords[i] = temp;
                                    }
                                    else break;
                            }
                            if(current_topwords > 10) current_topwords = 10;
                            tmp = tmp->next;
                    }
            }
    }
    
    void toptenwords()
    {
    int-topfreq=0;
    int minfreq=0;
    节点*topwords[11];
    int current_topwords=0;
    for(int m=0;m0;i--)
    {
    中频(topwords[i]>freq>topwords[i-1]>freq)
    {
    节点*temp=topwords[i-1];
    topwords[i-1]=topwords[i];
    topwords[i]=温度;
    }
    否则就断了;
    }
    如果(当前单词>10)当前单词=10;
    tmp=tmp->next;
    }
    }
    }
    
    步骤1(效率低下):

    通过插入排序将向量移动到已排序的容器中,但插入大小为10的容器(例如linkedlist或vector),并删除列表底部的所有元素

    步骤2(高效):


    与步骤1相同,但要跟踪列表底部项目的大小,如果当前项目太小,则完全跳过插入步骤。

    如果目标是累积单词频率,则包含单词链接列表的哈希表似乎是一种特殊的数据结构

    尽管如此,获得十个最高频率节点的有效方法是将每个节点插入优先级队列/堆,例如Fibonacci堆,该堆有O(1)个插入时间和O(n)个删除时间。假设哈希表上的迭代速度很快,该方法的运行时为O(n×O(1)+10×O(n))≡ O(n)。

    假设总共有n个单词,我们需要最频繁的k个单词(这里,k=10)

    如果n比k大得多,我所知道的最有效的方法是保持一个最小堆(即,堆中所有元素的最小频率都是顶部元素)。在每次迭代中,将下一个频率插入堆中,如果堆现在包含k+1个元素,则删除最小的元素。这样,堆始终保持k个元素的大小,随时包含迄今为止看到的k个最高频率元素。在处理结束时,在inc中读取k个最高频率元素恢复秩序

    时间复杂度:对于n个字中的每一个,我们做两件事:插入一个大小不超过k的堆,并删除最小的元素。每个操作花费O(logk)时间,因此整个循环需要O(nlogk)时间。最后,我们从大小不超过k的堆中读取k个元素,需要O(klogk)时间,总时间为O((n+k)logk)因为我们知道k绝对值
    void toptenwords()
    {
            int topfreq = 0;
            int minfreq = 0;
            node *topwords[11];
            int current_topwords = 0;
    
            for(int m = 0; m < HASHTABLESIZE; m++) // Go through the entire hast table
            {
                    node* tmp;
                    tmp = hashtable[m];
    
                    while(tmp != NULL) // Walk through the entire linked list
                    {
                            topwords[current_topwords] = tmp;
                            current_topwords++;
                            for(int i = current_topwords - 1; i > 0; i--)
                            {
                                    if(topwords[i]->freq > topwords[i - 1]->freq)
                                    {
                                            node *temp = topwords[i - 1];
                                            topwords[i - 1] = topwords[i];
                                            topwords[i] = temp;
                                    }
                                    else break;
                            }
                            if(current_topwords > 10) current_topwords = 10;
                            tmp = tmp->next;
                    }
            }
    }