如何解决BK-Tree实现的插入时间更多地是如何减少的
|| 以下是我写BK-Tree的尝试,对于150000
字文件,大约需要8 seconds
有什么办法可以减少这个时间。
以下是我的代码
#include <stdio.h>
#include <string>
#include <vector>
#include <fstream>
#include <iostream>
#include <sstream>
#include \"Timer.h\"
class BkTree {
public:
BkTree();
~BkTree();
void insert(std::string m_item);
private:
size_t Editdistance( const std::string &s,const std::string &t );
struct Node {
std::string m_item;
size_t m_distToParent;
Node *m_firstChild;
Node *m_nextSibling;
Node(std::string x,size_t dist);
~Node();
};
Node *m_root;
int m_size;
protected:
};
BkTree::BkTree() {
m_root = NULL;
m_size = 0;
}
BkTree::~BkTree() {
if( m_root )
delete m_root;
}
BkTree::Node::Node(std::string x,size_t dist) {
m_item = x;
m_distToParent = dist;
m_firstChild = m_nextSibling = NULL;
}
BkTree::Node::~Node() {
if( m_firstChild )
delete m_firstChild;
if( m_nextSibling )
delete m_nextSibling;
}
void BkTree::insert(std::string m_item) {
if( !m_root ){
m_size = 1;
m_root = new Node(m_item,-1);
return;
}
Node *t = m_root;
while( true ) {
size_t d = Editdistance( t->m_item,m_item );
if( !d )
return;
Node *ch = t->m_firstChild;
while( ch ) {
if( ch->m_distToParent == d ) {
t = ch;
break;
}
ch = ch->m_nextSibling;
}
if( !ch ) {
Node *newChild = new Node(m_item,d);
newChild->m_nextSibling = t->m_firstChild;
t->m_firstChild = newChild;
m_size++;
break;
}
}
}
size_t BkTree::Editdistance( const std::string &left,const std::string &right ) {
size_t asize = left.size();
size_t bsize = right.size();
std::vector<size_t> prevrow(bsize+1);
std::vector<size_t> thisrow(bsize+1);
for(size_t i = 0; i <= bsize; i++)
prevrow[i] = i;
for(size_t i = 1; i <= asize; i ++) {
thisrow[0] = i;
for(size_t j = 1; j <= bsize; j++) {
thisrow[j] = std::min(prevrow[j-1] + size_t(left[i-1] != right[j-1]),1 + std::min(prevrow[j],thisrow[j-1]) );
}
std::swap(thisrow,prevrow);
}
return prevrow[bsize];
}
void trim(std::string& input_str) {
if(input_str.empty()) return;
size_t startIndex = input_str.find_first_not_of(\" \");
size_t endindex = input_str.find_last_not_of(\"\\r\\n\");
std::string temp_str = input_str;
input_str.erase();
input_str = temp_str.substr(startIndex,(endindex-startIndex+ 1) );
}
int main( int argc,char **argv ) {
BkTree *pDictionary = new BkTree();
std::ifstream dictFile(\"D:\\\\dictionary.txt\");
Timer *t = new Timer(\"Time Taken to prepare Tree = \");
std::string line;
if (dictFile.is_open()) {
while (! dictFile.eof() ) {
std::getline (dictFile,line);
trim(line);
pDictionary->insert(line);
}
dictFile.close();
}
delete t;
delete pDictionary;
return 0;
}
class Timer {
public:
Timer (const std::string &name = \"undef\");
~Timer (void);
private:
std::string m_name;
std::clock_t m_started;
protected:
};
Timer::Timer (const std::string &name) : m_name(name),m_started(clock()) {
}
Timer::~Timer (void) {
double secs = static_cast<double>(std::clock() - m_started) / CLOCKS_PER_SEC;
std::cout << m_name << \": \" << secs << \" secs.\" << std::endl;
}
解决方法
您可以通过消除I / O来减少时间。要测试算法,请从方程式中删除不直接在程序控制下的尽可能多的对象。例如,操作系统控制着I / O,它不受您的控制。常量文本数组消除了很多操作系统的参与(操作系统仍然可以根据操作系统内存分配来对数组进行分页)。
接下来,大多数树结构都是面向数据的。它们的执行时间取决于数据。尝试三组数据:升序,“随机”和降序。注意每个时间。
查看循环并排除所有常量。在循环中创建临时变量,以便在内部循环中进行常量计算。删除不必要的操作。
最后,如果您的程序和算法非常健壮,请执行其他项目。仅在必要时进行优化。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。