 C++'da sonek ağacını uygulayın. Giriş dizileri yalnızca küçük İngilizce alfabesinden ("a" - "z") karakterler içerir.
Elbette, burada C++'da bir sonek ağacı uygulaması var. ``` #include <iostream> #include <vector> #include <unordered_map> namespace std; class SuffixTree { özel: yapı Düğümü { int start; niyet etmek; Düğüm* sonekiBağlantı; unordered_map<char, Node*> çocuklar; Düğüm(int başlangıç, int bitiş) { bu->başlangıç = başlangıç; bu->son = son; sonekLink = nullptr; } int getLength() { dönüş min(bitiş, (int)metin.size()) - başlangıç; } string getText() { return text.substr(start, getLength()); } void addChild(Düğüm* düğümü) { char c = metin[düğüm->başlangıç]; çocuklar[c] = düğüm; } }; düğüm* kökü; Düğüm* activeNode; int aktif Kenar; int aktifUzunluk; kalan int; dize metni; public: SuffixTree(string text) { this->text = text; kök = yeni Düğüm(-1, -1); activeNode = kök; aktif Kenar = -1; aktifUzunluk = 0; kalan = 0; inşa etmek(); } geçersiz yazdır() { yazdırYardımcı(kök, 0); } özel: Düğüm* bölünmüş(Düğüm* düğümü) { if (activeLength == 0) { dönüş düğümü; } char startChar = metin[node->start + activeEdge]; Düğüm* çocuk = düğüm->çocuklar[startChar]; int splitEnd = düğüm->başlangıç + activeEdge + activeLength - 1; if (child->getLength() == activeLength) { çocuğu döndürür; } Düğüm* splitNode = new Node(child->start, child->start + activeLength); düğüm->addChild(splitNode); çocuk->başlangıç += activeLength; splitNode->addChild(child); splitNode'u döndür; } void extension(int dizini) { kalan++; Düğüm* lastNode = nullptr; while (kalan > 0) { if (activeLength == 0) { activeEdge = index; } char nextChar = metin[dizin]; if (activeNode->children[nextChar] == nullptr) { Düğüm* yeniDüğüm = yeni Düğüm(index, text.size()); activeNode->addChild(newNode); eğer (lastNode != nullptr) { lastNode->suffixLink = activeNode; } lastNode = activeNode; } else { Düğüm* nextNode = activeNode->children[nextChar]; if (walkDown(nextNode)) { devam et; } char nextChar2 = metin[nextNode->start + activeLength]; if (nextChar == nextChar2) { activeLength++; eğer (lastNode != nullptr) { lastNode->suffixLink = activeNode; } kırmak; } Düğüm* splitNode = split(nextNode); Düğüm* yeni Düğüm = yeni Düğüm(dizin, metin.size()); activeNode->addChild(splitNode); newNode->addChild(splitNode); activeNode->addChild(newNode); eğer (lastNode != nullptr) { lastNode->suffixLink = newNode; } lastNode = yeniNode; } geriye kalan--; if (activeNode == root && activeLength > 0) { activeLength--; activeEdge = dizin - kalan + 1; } else { activeNode = activeNode->sonekLink != nullptr ? activeNode->suffixLink : kök; } } } bool walkDown(Düğüm* düğüm) { int uzunluk = düğüm->getLength(); if (activeLength >= uzunluk) { activeEdge += uzunluk; activeLength -= uzunluk; activeNode = düğüm; doğru dönüş; } yanlış döndür; } void build() { for (int i = 0; i < text.size(); i++) { extension(i); } } void printHelper(Node* node, int level) { cout << string(level * 2, ' ') << node->getText() << endl; for (otomatik çocuk : düğüm->çocuklar) { printHelper(child.second, seviye + 1); } } }; int main() { string metin = "abcabxabcd"; SuffixTree st(metin); st.print(); 0 dönüşü; } ```