Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> C++

BK Tree เบื้องต้นใน C++


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

เช่นเดียวกับต้นไม้อื่น ๆ ต้นไม้ BK ยังประกอบด้วยโหนดและขอบด้วย โหนดเป็นตัวแทนของคำในพจนานุกรม ขอบมีน้ำหนักจำนวนเต็มบางตัวที่ให้ข้อมูลเกี่ยวกับการแก้ไขระยะทางจากโหนดหนึ่งไปยังอีกโหนดหนึ่ง

พิจารณาพจนานุกรมที่มีคำศัพท์ { book, books, boo, cake, cape} −

BK Tree เบื้องต้นใน C++

บีเคทรี

โน้ตทุกตัวใน 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