BK tree หรือ Burkhard tree เป็นโครงสร้างข้อมูลที่มักใช้ตรวจสอบการสะกดตามระยะทาง Levenshtein นอกจากนี้ยังใช้สำหรับสตริงที่ตรงกับคุณลักษณะการแก้ไขอัตโนมัติที่สามารถใช้สร้างโครงสร้างข้อมูลนี้ได้ สมมติว่าเรามีคำบางคำในพจนานุกรมและเราจำเป็นต้องตรวจสอบคำอื่นๆ เพื่อหาข้อผิดพลาดในการสะกดคำ เราจำเป็นต้องมีการรวบรวมคำที่ใกล้เคียงกับคำที่กำหนดซึ่งมีการตรวจสอบการสะกดคำ ตัวอย่างเช่น ถ้าเรามีคำว่า "uck" คำที่ถูกต้องอาจเป็นได้ (รถบรรทุก เป็ด เป็ด ห่วย) ดังนั้นการสะกดผิดสามารถแก้ไขได้โดยการลบคำหรือเพิ่มคำใหม่แทนที่ตัวอักษรด้วยตัวอักษรที่เหมาะสม ใช้ระยะแก้ไขเป็นพารามิเตอร์และตรวจสอบการสะกดด้วยพจนานุกรม
เช่นเดียวกับต้นไม้อื่น ๆ ต้นไม้ BK ยังประกอบด้วยโหนดและขอบด้วย โหนดเป็นตัวแทนของคำในพจนานุกรม ขอบมีน้ำหนักจำนวนเต็มบางตัวที่ให้ข้อมูลเกี่ยวกับการแก้ไขระยะทางจากโหนดหนึ่งไปยังอีกโหนดหนึ่ง
พิจารณาพจนานุกรมที่มีคำศัพท์ { book, books, boo, cake, cape} −

บีเคทรี
โน้ตทุกตัวใน BK Tree มีโหนดย่อยหนึ่งโหนดที่มีระยะการแก้ไขเท่ากัน หากเราพบการชนกันในระยะแก้ไขขณะแทรกโหนด เราจะเผยแพร่กระบวนการแทรกจนกว่าเราจะได้ลูกที่ถูกต้อง การแทรกทุกครั้งเริ่มต้นด้วยโหนดรูท โหนดรูทสามารถเป็นคำใดก็ได้ จนถึงตอนนี้เราได้เรียนรู้ว่า Bk Tree คืออะไร ทีนี้มาดูวิธีค้นหาคำที่ใกล้ที่สุดที่ถูกต้องกัน ก่อนอื่น เราต้องตั้งค่าความคลาดเคลื่อน ค่าความคลาดเคลื่อนนี้เป็นเพียงระยะการแก้ไขสูงสุดระหว่างคำที่สะกดผิดและคำที่ถูกต้อง
ในการค้นหาคำที่ถูกต้องที่มีสิทธิ์ภายในขีดจำกัดความอดทน เราใช้กระบวนการวนซ้ำ แต่สิ่งนี้มีความซับซ้อนสูงกว่า ดังนั้นตอนนี้ BK tree เริ่มดำเนินการ เนื่องจากเรารู้ว่าแต่ละโหนดในไบนารีทรีถูกสร้างขึ้นตามระยะการแก้ไขจากพาเรนต์ ดังนั้นเราจึงสามารถเปลี่ยนจากโหนดรูทไปยังโหนดเฉพาะที่อยู่ภายในขีดจำกัดความคลาดเคลื่อนได้โดยตรง ถ้า TOL เป็นขีดจำกัดความคลาดเคลื่อนและแก้ไขระยะทางของโหนดปัจจุบันจากโหนดที่สะกดผิดคือ dist ตอนนี้เราจะทำซ้ำเฉพาะเด็กที่มีระยะการแก้ไขอยู่ในช่วง
[dist - TOL, dist+TOL] ซึ่งช่วยลดความซับซ้อนในระดับที่มากขึ้น
ตัวอย่าง
โปรแกรมแสดงการทำงาน -
#include "bits/stdc++.h"
using namespace std;
#define MAXN 100
#define TOL 2
#define LEN 10
struct Node {
string word;
int next[2*LEN];
Node(string x):word(x){
for(int i=0; i<2*LEN; i++)
next[i] = 0;
}
Node() {}
};
Node RT;
Node tree[MAXN];
int ptr;
int min(int a, int b, int c) {
return min(a, min(b, c));
}
int editDistance(string& a,string& b) {
int m = a.length(), n = b.length();
int dp[m+1][n+1];
for (int i=0; i<=m; i++)
dp[i][0] = i;
for (int j=0; j<=n; j++)
dp[0][j] = j;
for (int i=1; i<=m; i++) {
for (int j=1; j<=n; j++) {
if (a[i-1] != b[j-1])
dp[i][j] = min( 1 + dp[i-1][j], 1 + dp[i][j-1], 1 + dp[i-1][j-1] );
else
dp[i][j] = dp[i-1][j-1];
}
}
return dp[m][n];
}
void insertValue(Node& root,Node& curr) {
if (root.word == "" ){
root = curr;
return;
}
int dist = editDistance(curr.word,root.word);
if (tree[root.next[dist]].word == ""){
ptr++;
tree[ptr] = curr;
root.next[dist] = ptr;
}
else{
insertValue(tree[root.next[dist]],curr);
}
}
vector <string> findCorrectSuggestions(Node& root,string& s){
vector <string> corrections;
if (root.word == "")
return corrections;
int dist = editDistance(root.word,s);
if (dist <= TOL) corrections.push_back(root.word);
int start = dist - TOL;
if (start < 0)
start = 1;
while (start < dist + TOL){
vector <string> temp = findCorrectSuggestions(tree[root.next[start]],s);
for (auto i : temp)
corrections.push_back(i);
start++;
}
return corrections;
}
int main(){
string dictionary[] = {"book","cake","cart","books", "boo" };
ptr = 0;
int size = sizeof(dictionary)/sizeof(string);
for(int i=0; i<size; i++){
Node tmp = Node(dictionary[i]);
insertValue(RT,tmp);
}
string word1 = "ok";
string word2 = "ke";
vector <string> match = findCorrectSuggestions(RT,word1);
cout<<"Correct words suggestions from dictionary for : "<<word1<<endl;
for (auto correctWords : match)
cout<<correctWords<<endl;
match = findCorrectSuggestions(RT,word2);
cout<<"Correct words suggestions from dictionary for : "<<word2<<endl;
for (auto correctWords : match)
cout<<correctWords<<endl;
return 0;
} ผลลัพธ์
Correct words suggestions from dictionary for : ok book boo Correct words suggestions from dictionary for : ke cake