Computer >> कंप्यूटर ट्यूटोरियल >  >> प्रोग्रामिंग >> C++

C++ में BK ट्री परिचय


BK ट्री या बर्कहार्ड ट्री (Burkhard tree) एक प्रकार की डेटा संरचना है जिसका उपयोग आमतौर पर लेवेंश्टाइन दूरी (Levenshtein distance) के आधार पर स्पेल चेक करने के लिए किया जाता है। इसका उपयोग स्ट्रिंग मिलान के लिए ऑटोकरेक्ट फीचर बनाने के लिए भी किया जाता है। मान लें कि हमारे पास एक डिक्शनरी में कुछ शब्द हैं और हमें स्पेलिंग त्रुटियों के लिए कुछ अन्य शब्दों की जांच करने की आवश्यकता है। हमें दिए गए शब्द के करीब शब्दों का एक संग्रह चाहिए जिसकी स्पेलिंग जांची जानी है। उदाहरण के लिए, यदि हमारे पास शब्द "uck" है तो सही शब्द (truck, duck, duck, suck) हो सकते हैं। इसलिए स्पेलिंग गलतियों को एक शब्द को हटाकर या एक नया शब्द जोड़कर या एक अक्षर को उपयुक्त अक्षर से बदलकर ठीक किया जा सकता है। डिक्शनरी के साथ स्पेलिंग की जांच करने के लिए संपादन दूरी (edit distance) को पैरामीटर के रूप में उपयोग करना।

अन्य सभी ट्री की तरह, BK ट्री में भी नोड्स और एज होते हैं। नोड्स डिक्शनरी में शब्दों को दर्शाते हैं। एज में कुछ पूर्णांक वजन होते हैं जो एक नोड से दूसरे नोड तक संपादन दूरी के बारे में जानकारी देते हैं।

{ book, books, boo, cake, cape } शब्दों वाले डिक्शनरी पर विचार करें -

C++ में BK ट्री परिचय

BK ट्री

BK ट्री में हर नोड का ठीक एक चाइल्ड नोड होता है जिसकी संपादन दूरी समान होती है। यदि हम नोड्स डालते समय संपादन दूरी में कुछ टकराव (collision) का सामना करते हैं, तो हम सम्मिलन प्रक्रिया को तब तक प्रसारित (propagate) करेंगे जब तक हमें सही चाइल्ड न मिल जाए। प्रत्येक सम्मिलन रूट नोड से शुरू होता है, रूट नोड कोई भी शब्द हो सकता है। अब तक हमने सीखा कि BK ट्री क्या है। अब देखते हैं कि सही निकटतम शब्द कैसे ढूंढें। सबसे पहले, हमें सहनशीलता मान (tolerance value) सेट करने की आवश्यकता है। यह सहनशीलता मान मेरे गलत वर्तनी वाले शब्द और सही शब्द के बीच अधिकतम संपादन दूरी के अलावा कुछ नहीं है।

सहनशीलता सीमा के भीतर योग्य सही शब्द ढूंढने के लिए हम पुनरावृत्ति (iteration) की प्रक्रिया का उपयोग करते हैं। लेकिन इसकी जटिलता अधिक होती है इसलिए अब BK ट्री काम आता है क्योंकि हम जानते हैं कि बाइनरी ट्री में प्रत्येक नोड अपने पैरेंट से संपादन दूरी के आधार पर बनाया जाता है। तो हम सीधे रूट नोड से उस विशिष्ट नोड पर जा सकते हैं जो सहनशीलता सीमा के भीतर स्थित है। यदि 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 << "डिक्शनरी से सही शब्द सुझाव: " << word1 << endl;
    for (auto correctWords : match)
        cout << correctWords << endl;
    match = findCorrectSuggestions(RT,word2);
    cout << "डिक्शनरी से सही शब्द सुझाव: " << word2 << endl;
    for (auto correctWords : match)
        cout << correctWords << endl;
    return 0;
}

आउटपुट

डिक्शनरी से सही शब्द सुझाव: ok
book
boo
डिक्शनरी से सही शब्द सुझाव: ke
cake
  1. C++ में ट्री में सभी सेब इकट्ठा करने का न्यूनतम समय C++ में ट्री में सभी सेब इकट्ठा करने का न्यूनतम समय

    मान लीजिए हमारे पास n वर्टेक्स वाला एक अनडायरेक्टेड ट्री है जो 0 से n-1 तक नंबर किए गए हैं, जिनके वर्टेक्स में कुछ सेब हैं। हम ट्री के एक एज पर चलने में 1 सेकंड खर्च करते हैं। हमें वर्टेक्स 0 से शुरू करके ट्री में सभी सेब इकट्ठा करने और इस वर्टेक्स पर वापस आने में खर्च होने वाले न्यूनतम समय (सेकंड म

  1. C++ में ट्री नोड्स डिलीट करें C++ में ट्री नोड्स डिलीट करें

    मान लीजिए हमारे पास एक ट्री है, यह ट्री नोड 0 पर रूटेड है, यह निम्नानुसार दिया गया है -नोड्स की संख्या nodes हैi-वें नोड का मान value[i] हैi-वें नोड का पैरेंट parent[i] हैहमें हर उस सबट्री को हटाना है जिसके नोड्स के मानों का योग 0 है, ऐसा करने के बाद ट्री में शेष नोड्स की संख्या लौटाएं। यदि ट्री इस

  1. C++ में ट्री डायमीटर C++ में ट्री डायमीटर

    मान लीजिए हमारे पास एक अनडायरेक्टेड ट्री है; हमें इसका डायमीटर ढूंढना है - उस ट्री में सबसे लंबे पथ में एज की संख्या उस ट्री का डायमीटर है। यहां ट्री को एज लिस्ट के रूप में दिया गया है जहां edges[i] = [u, v] नोड्स u और v के बीच एक बायडायरेक्शनल एज है। प्रत्येक नोड के लेबल सेट {0, 1, ..., edges.lengt