實驗五:小型文本搜索引擎的實現(12~15小時)
[問題描述]
隨著互聯網技術的快速發展,如何從海量數據中找到所需的內容不僅是研究人員的熱點問題,許多IT公司也推出了自己的搜索引擎,如Google、百度和Bing。搜索引擎的核心是如何為網頁建立有效的索引,從而快速找到並匹配查詢關鍵詞,及時將搜索結果返回給用戶。在本實驗中,請實現壹個英文單詞的二叉查找樹,並根據輸入的英文單詞進行搜索,同時給出單詞在文檔中的位置信息。
[實驗目的]
(1)掌握二叉查找樹的施工流程;
(2)掌握在二叉查找樹中插入和刪除節點的操作;
(3)掌握二叉樹的前序和中序遍歷;
(4)運用二叉查找樹解決實際問題。
[實驗內容和要求]
(1)構建二叉查找樹:
①從文件中讀入內容,過濾掉阿拉伯數字和標點符號,將英文字母的所有大寫形式轉換成小寫形式。
②.按照英文字母表的順序構建壹個英文單詞二叉查找樹。當兩個英文單詞的首字母相同時,按第二個字母排序,以此類推。
③.為每個英文單詞建立壹個單鏈表,用來存儲該單詞在文檔中的位置信息(即該單詞在文檔中是什麽單詞,序號從1開始)。如果壹個單詞在壹個文檔中出現多次,那麽鏈表將包含多個節點,並按照該單詞在文檔中出現的順序(位置信息)進行升序排序。
(2)穿越二叉查找樹:
(1)實現二叉查找樹的前序遍歷,從而找出出現頻率最高的詞;
(2)搜索:輸入壹個待搜索的單詞,預先以遍歷的方式從二叉查找樹中搜索該單詞,如果能找到該單詞,則輸出該單詞在原文檔中的位置信息,否則提示該文檔不包含所搜索的單詞;
③.實現二叉查找樹的中階遍歷,並將遍歷結果保存到壹個文件(words.txt)中。(要求:每個單詞占壹行,每行依次記錄單詞、單詞出現的次數、單詞在文檔中的位置信息。)
(3)刪除節點:
1.給定壹個停用詞列表(停用詞是指對搜索沒有影響的詞,如:of,and,a,an,the等。),依次刪除二叉查找樹中的單詞(不僅刪除節點,還清空記錄單詞位置信息的單鏈表);
(2)搜索時,當輸入的搜索詞是停用詞時,將不進行查詢。
[被選作內容]
(1)允許壹次輸入兩個或兩個以上的詞進行查詢,即先獲取這些詞在文檔中的位置信息,再分析這些詞的位置信息,判斷這些詞在原始文檔中是否連續出現。
(2)嘗試從多個文檔中讀取內容,建立二叉查找樹,並搜索多個文檔。
# include & ltiostream & gt
# include & lt字符串& gt
# include & ltcstring & gt
使用?命名空間?std
班級?雙星系統
{公共:
字符串?數據;
int?w;
BinaryTreeNode?* leftchild
BinaryTreeNode?*右孩子;
BinaryTreeNode?*父母;
int?位置[50];
BinaryTreeNode(字符串?a,int?位置)
{
數據= a;
w = 1;
leftchild = NULL
rightchild = NULL
parent = NULL
位置[0]=位置;
}
};
班級?BSTree
{公共:
BinaryTreeNode?* root
BSTree(){ root = NULL;}
作廢?插入(字符串?a,int?position);
作廢?刪除(字符串?關鍵);
BinaryTreeNode?*搜索(字符串?key,BinaryTreeNode * & amp?pr,BinaryTreeNode?* & amp家長);
作廢?in order(binary treenode * & amp;根);
作廢?預訂(BinaryTreeNode * & amp根);
};
作廢?in order(binary treenode * & amp;根)
{
如果(根)
{
in order(root-& gt;left child);
cout & lt& ltroot-& gt;數據;
cout & lt& lt"?"& lt& ltroot-& gt;w & lt& ltendl
in order(root-& gt;right child);
}
}
作廢?BSTree::PreOrder(binary treenode * & amp;?根)
{
如果(根)
{
cout & lt& ltroot-& gt;數據;
cout & lt& lt"?"& lt& ltroot-& gt;w & lt& ltendl
前序(根->;left child);
前序(根->;right child);
}
}
BinaryTreeNode?*BSTree::Search(string?key,BinaryTreeNode * & amp?pr,BinaryTreeNode * & amp?父母)
{
BinaryTreeNode?* p =根;
pr =根;
while(p)
{
父母= p;
if(key & lt;p->;數據)
{
pr = p;
p = p-& gt;leftchild
}
不然呢?if(key & gt;p->;數據)
{
pr = p;
p = p-& gt;右孩子;
}
其他
回歸?p;
}
回歸?NULL
}
作廢?BSTree::Insert(字符串?a,int?位置)
{
BinaryTreeNode?*pr,*p,* pp = NULL
p=Search(a,pr,PP);
如果(p!=空)
{
p->;w++;
p->;pos[p->;w-1]= position;
返回;
}
BinaryTreeNode?* r =新?BinaryTreeNode(a,position);
如果(!根)
root = r;
不然呢?如果(a & ltPP-& gt;數據)
PP-& gt;left child = r;
其他
PP-& gt;right child = r;
}
作廢?BSTree::Delete(字符串?關鍵)
{
BinaryTreeNode?*p,*pr,* pp
p =搜索(key,pp,pr);
if(p==NULL)
返回;
如果(p->;左童& amp& ampp->;右兒童)
{
BinaryTreeNode?* s = p-& gt;rightchild,* PS = p;
while(s->;左孩子)
{
PS = s;
s = s-& gt;leftchild
}
p->;data = s-& gt;數據;
p->;w = s-& gt;w;
for(int?I = 0;我& lts-& gt;w;i++)
{
p->;pos[I]= s-& gt;pos[I];
}
pp = ps
p = s;
}
如果(p->;左孩子)
{
如果(PP-& gt;leftchild==p)
{
PP-& gt;left child = p-& gt;leftchild
p->;left child-& gt;parent = pp
}
其他
{
PP-& gt;right child = p-& gt;leftchild
p->;left child-& gt;parent = pp
}
}
不然呢?如果(p->;右兒童)
{
如果(PP-& gt;leftchild==p)
{
PP-& gt;left child = p-& gt;右孩子;
p->;rightchild = pp
}
其他
{
PP-& gt;right child = p-& gt;右孩子;
p->;right child->;parent = pp
}
}
其他
{
如果(PP-& gt;leftchild==p)
PP-& gt;leftchild = NULL
其他
PP-& gt;rightchild = NULL
}
刪除?p;
}
字符串?Word(int?我)
{
字符串?word[9]=
{“壹個”,“壹個”,“和”,
“是”、“是”、“該”,
“of”,“was”,“were”,
};
回歸?word[I];
}
int?主()
{
BSTree?*SearchTree=new?BSTree
夏爾?ch;
字符串?str
int?I = 2;
int?pos = 1;
while(cin.get(ch))
{
if(ch & gt;= ' a ' & amp& ampch & lt='z ')
{
str.insert(str.end(),ch);
I = 0;
}
其他
{
if(ch & gt;= ' A ' & amp& ampch & lt='Z ')
{
str.insert(str.end(),char(ch+32));
I = 0;
}
其他
{
如果(i==0)
{
搜索樹-& gt;插入(字符串,位置);
pos++;
str.erase(str.begin()、str . end());
}
i++;
}
}
if(ch=='# ')
打破;
}
搜索樹-& gt;InOrder(搜索樹-& gt;根);
for(int?k = 0;k & lt9;k++)
{
搜索樹-& gt;刪除(單詞(k));
}
搜索樹-& gt;預訂(搜索樹->;根);
字符串?abc
cout & lt& lt"請輸入您要查找的字符:";
BinaryTreeNode?*q,*p,* s;
而(CIN & gt;& gtabc)
{
p = search tree-& gt;搜索(abc,q,s);
如果(p!=空)
{
cout & lt& ltabc & lt& lt"文本中出現的次數是:"
cout & lt& lt"它們的位置是:";
for(int?j = 0;j & ltp->;w;j++)
{
cout & lt& ltp->;pos[j]& lt;& lt"?";
}
}
其他
cout & lt& lt“這個字符串不在正文裏!”;
cout & lt& ltendl
cout & lt& lt"請輸入您要查找的字符:";
}
}