現在、データ構造の実行時間に応じて、頻度を計算するためにハッシュ テーブルの作成に取り組んでいます。O(1)の挿入、O(n)の悪いルックアップ時間など。
std::map
とハッシュテーブルの違いを数人に尋ねたところ、次のような回答がありました。
"std::map
要素を二分木として追加するとO(log n)が発生しますが、実装するハッシュ テーブルではO(n)になります。"
したがって、リンクされたリストの配列 (個別の連鎖用)構造を使用してハッシュ テーブルを実装することにしました。以下のコードでは、ノードに 2 つの値を割り当てています。1 つはキー (単語)で、もう 1 つは値 (頻度)です。それは次のように機能します。インデックスが空の場合に最初のノードが追加されると、リンクされたリストの最初の要素として頻度0で直接挿入されます。すでにリストにある場合 (残念ながら検索にO(n)時間がかかります)、頻度を 1 増やします。見つからない場合は、単純にリストの先頭に追加します。
実装には多くのフローがあることを知っているので、周波数を効率的に計算するために、ここの経験豊富な人々に尋ねたいのですが、この実装をどのように改善できますか?
これまでに書いたコード。
#include <iostream>
#include <stdio.h>
using namespace std;
struct Node {
string word;
int frequency;
Node *next;
};
class linkedList
{
private:
friend class hashTable;
Node *firstPtr;
Node *lastPtr;
int size;
public:
linkedList()
{
firstPtr=lastPtr=NULL;
size=0;
}
void insert(string word,int frequency)
{
Node* newNode=new Node;
newNode->word=word;
newNode->frequency=frequency;
if(firstPtr==NULL)
firstPtr=lastPtr=newNode;
else {
newNode->next=firstPtr;
firstPtr=newNode;
}
size++;
}
int sizeOfList()
{
return size;
}
void print()
{
if(firstPtr!=NULL)
{
Node *temp=firstPtr;
while(temp!=NULL)
{
cout<<temp->word<<" "<<temp->frequency<<endl;
temp=temp->next;
}
}
else
printf("%s","List is empty");
}
};
class hashTable
{
private:
linkedList* arr;
int index,sizeOfTable;
public:
hashTable(int size) //Forced initalizer
{
sizeOfTable=size;
arr=new linkedList[sizeOfTable];
}
int hash(string key)
{
int hashVal=0;
for(int i=0;i<key.length();i++)
hashVal=37*hashVal+key[i];
hashVal=hashVal%sizeOfTable;
if(hashVal<0)
hashVal+=sizeOfTable;
return hashVal;
}
void insert(string key)
{
index=hash(key);
if(arr[index].sizeOfList()<1)
arr[index].insert(key, 0);
else {
//Search for the index throughout the linked list.
//If found, increment its value +1
//else if not found, add the node to the beginning
}
}
};