C++ 在一个很大的文件中搜索单词
给定一个大文件,我们需要存储单词,以便在固定时间内搜索单词。另外,我们将如何找到文件中10%最常出现的单词 到目前为止,我所取得的成就是通过trie实现来搜索单词。 请建议一些方法来找出10%最常用的单词C++ 在一个很大的文件中搜索单词,c++,C++,给定一个大文件,我们需要存储单词,以便在固定时间内搜索单词。另外,我们将如何找到文件中10%最常出现的单词 到目前为止,我所取得的成就是通过trie实现来搜索单词。 请建议一些方法来找出10%最常用的单词 #include<iostream> #include<cstdio> using namespace std; class Node { public: char value; Node* right; Node* down;
#include<iostream>
#include<cstdio>
using namespace std;
class Node
{
public:
char value;
Node* right;
Node* down;
Node()
{
right=down=NULL;
}
};
class Trie
{
public:
Node* head;
Trie()
{
head=NULL;
}
void insert(string s);
void search(string s);
};
void Trie::insert(string s)
{
if(head==NULL)
{
Node* f=new Node();
head=f;
Node* temp=f;
f->value=s[0];
for(int i=1;i<s.length();i++)
{
Node* n=new Node();
n->value=s[i];
temp->down=n;
temp=n;
if(i==s.length()-1)
n->down=NULL;
}
}
else
{
Node* ptr=head;
int i=0;
while(1)
{
if(i==s.length())break;
if(ptr->value==s[i])
{
i++;
if(ptr->down)
ptr=ptr->down;
else
{
Node* temp=new Node();
ptr->down=temp;
temp->value=s[i];
ptr=temp;
}
}
else if(ptr->value!=s[i])
{
if(ptr->right)
ptr=ptr->right;
else
{
Node*temp=new Node();
ptr->right=temp;
temp->value=s[i];
ptr=temp;
}
}
}
}
}
void Trie::search(string s)
{
Node* ptr=head;
int i=0;
while(1)
{
if(ptr->value==s[i])
{
//cout<<ptr->value<<endl;
ptr=ptr->down;
i++;
}
else if(ptr->value!=s[i])
{
ptr=ptr->right;
}
if(ptr==NULL)break;
}
if(i==s.length()+1)cout<<"String found\n";
else cout<<"String not found\n";
}
int main()
{
Trie t;
FILE* input;
char s[100];
input=fopen("big.txt","r");
int i=0;
while( (fgets(s,sizeof(s),input) ) !=NULL)
{
int i=0; int j=0;
char str[47];
while(s[i]!='\0')
{
if(s[i]==' ' || s[i+1]=='\0')
{
str[j]='\0';
j=0;
t.insert(str);
i++;
continue;
}
str[j]=s[i];
j++;
i++;
}
}
t.search("Dates");
//t.search("multinational");
fclose(input);
}
#包括
#包括
使用名称空间std;
类节点
{
公众:
字符值;
节点*右;
节点*向下;
节点()
{
右=下=空;
}
};
三类
{
公众:
节点*头;
Trie()
{
head=NULL;
}
空白插入(字符串s);
无效搜索(字符串s);
};
void Trie::insert(字符串s)
{
if(head==NULL)
{
Node*f=新节点();
水头=f;
节点*temp=f;
f->value=s[0];
对于(int i=1;ivalue=s[i];
温度->下降=n;
温度=n;
如果(i==s.length()-1)
n->down=NULL;
}
}
其他的
{
节点*ptr=头部;
int i=0;
而(1)
{
如果(i==s.length())中断;
如果(ptr->value==s[i])
{
i++;
如果(ptr->down)
ptr=ptr->down;
其他的
{
Node*temp=新节点();
ptr->down=温度;
温度->值=s[i];
ptr=温度;
}
}
否则如果(ptr->value!=s[i])
{
如果(ptr->右侧)
ptr=ptr->右侧;
其他的
{
Node*temp=新节点();
ptr->右侧=温度;
温度->值=s[i];
ptr=温度;
}
}
}
}
}
void Trie::搜索(字符串s)
{
节点*ptr=头部;
int i=0;
而(1)
{
如果(ptr->value==s[i])
{
//库特里赫特;
}
如果(ptr==NULL)中断;
}
如果(i==s.length()+1)不能则散列将允许您在固定时间内查找单词
您可能会使用类似于快速排序中使用的某种分区来查找文件中至少出现10%的单词。显而易见的解决方案是将文件内容存储在一些适当的STL容器中,例如std::set
,然后在该容器上运行find()
如果您坚持手动执行此操作,二叉树的增长速度将随着您在其中输入的数据量的增加而变得越来越慢。此外,您必须保持平衡。对于大量数据而言,带链接的二叉树将是更有效的ADT。如果您使用树,则无法获得恒定时间。您正在构建的二叉树具有对数时间复杂性
如果有可能建立一个索引,考虑一个。这仍然不能帮助你用固定的时间(我看不出你怎么能做到这一点)。但是,它可以帮助你找出最常用的词,因为它的每一个字都存储了文件中找到单词的位置。实际上,你可以将它组合到你的树中。 < p>这里是使用优先级队列、映射和TrE的类似C++代码。
为了简单起见,它可以从向量字符串中读取,但可以很容易地修改为从文件中读取单词
//查找文件或流中的k个频繁字,C++ < /P>
//这是优先级队列的工作解决方案,供您参考
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
#define K_TH 3
class TrieNode;
typedef struct HeapNode
{
string word;
int frequency;
HeapNode(): frequency(0), word(""){} ;
TrieNode *trieNode;
}HeapNode;
class TrieNode
{
private:
int frequency = 0;
bool m_isLeaf = false;
string word = "";
unordered_map<char, TrieNode*> children;
HeapNode *heapNode = NULL;
public:
TrieNode() {}
TrieNode(char c)
{
children[c] = new TrieNode();
this->m_isLeaf = false;
}
void setWord(string word)
{
this->word = word;
}
string getWord()
{
return this->word;
}
bool isLeaf(void)
{
return this->m_isLeaf;
}
void setLeaf(bool leaf)
{
this->m_isLeaf = leaf;
}
TrieNode* getChild(char c)
{
if (children[c] != NULL)
return children[c];
return NULL;
}
void insert(char c)
{
children[c] = new TrieNode();
}
int getFrequency()
{
return this->frequency;
}
void setFrequency(int frequency)
{
this->frequency = frequency;
}
void setHeapNode(HeapNode *heapNode)
{
this->heapNode = heapNode;
}
HeapNode* getHeapNode()
{
return heapNode;
}
bool operator()(HeapNode* &a, HeapNode* &b)
{
return (a->frequency > b->frequency);
}
};
class Trie
{
private:
TrieNode *root = NULL;
public:
Trie()
{
if (!root)
{
this->root = new TrieNode();
}
}
TrieNode* insert(string word)
{
if (!root)
root = new TrieNode();
TrieNode* current = root;
int length = word.length();
//insert "abc"
for(int i = 0; i < length; ++i)
{
if (current->getChild(word.at(i)) == NULL)
{
current->insert(word.at(i));
}
current = current->getChild(word.at(i));
}
current->setLeaf(true);
current->setWord(word);
current->setFrequency(current->getFrequency() + 1);
return current;
}
};
struct cmp
{
bool operator()(HeapNode* &a, HeapNode* &b)
{
return (a->frequency > b->frequency);
}
};
typedef priority_queue<HeapNode*, vector<HeapNode*>, cmp > MinHeap;
void insertUtils(Trie *root, MinHeap &pq, string word )
{
if (!root)
return;
TrieNode* current = root->insert(word);
HeapNode *heapNode = current->getHeapNode();
if(heapNode)// if word already present in heap
{
heapNode->frequency += 1;
}else if (pq.empty() || pq.size() < K_TH)
{// if word not present in heap and heap is not full;
heapNode = new HeapNode();
heapNode->word = word;
heapNode->frequency = 1;
heapNode->trieNode = current;
current->setHeapNode(heapNode);
pq.push(heapNode);
}else if (pq.top()->frequency < current->getFrequency())
{ // if word is not present and heap is full;
HeapNode *temp = pq.top();
//remove first element and add current word
pq.pop();
delete temp;
heapNode = new HeapNode();
current->setHeapNode(heapNode);
pq.push(heapNode);
}
}
void printKMostFrequentWords(vector<std::string> input)
{
Trie *root = new Trie();
MinHeap minHeap;
for (vector<string>::iterator it = input.begin(); it != input.end(); ++it)
{
insertUtils(root, minHeap, *it);
}
while(!minHeap.empty())
{
HeapNode *heapNode = minHeap.top();
cout << heapNode->word << ":" << heapNode->frequency << endl;
minHeap.pop();
}
}
int main() {
vector<std::string>input( {
"abc", "def", "ghi",
"jkl", "abc", "def",
"mno", "xyz", "abc"
} ) ;
printKMostFrequentWords(input);
}
#包括
#包括
#包括
#包括
使用名称空间std;
#定义K_TH 3
类三元组;
类型定义结构HeapNode
{
字符串字;
整数频率;
HeapNode():频率(0),单词(“”{};
三元组*三元组;
}HeapNode;
类三节点
{
私人:
整数频率=0;
bool m_isLeaf=false;
字串=”;
无序映射子对象;
HeapNode*HeapNode=NULL;
公众:
三节点(){}
三节点(字符c)
{
儿童[c]=新三元组();
此->m_isLeaf=false;
}
无效设置字(字符串字)
{
这个->字=字;
}
字符串getWord()
{
返回此->单词;
}
布尔岛(空)
{
返回此->m_isLeaf;
}
无效设置叶(布尔叶)
{
这->m_isLeaf=leaf;
}
三元组*getChild(字符c)
{
if(children[c]!=NULL)
返回儿童[c];
返回NULL;
}
空白插入(字符c)
{
儿童[c]=新三元组();
}
int getFrequency()
{
返回此->频率;
}
无效设置频率(整数频率)
{
这个->频率=频率;
}
void setHeapNode(HeapNode*HeapNode)
{
此->heapNode=heapNode;
}
HeapNode*getHeapNode()
{
返回heapNode;
}
布尔运算符()(HeapNode*&a、HeapNode*&b)
{
返回(a->frequency>b->frequency);
}
};
三类
{
私人:
三节点*根=空;
公众:
Trie()
{
如果(!root)
{
此->根=新的三节点();
}
}
三节点*插入(字符串字)
{
如果(!root)
根=新的三节点();
三极*电流=根;
int length=word.length();
//插入“abc”
对于(int i=0;igetChild(word.at(i))==NULL)