bump product version to 7.6.3.2-android
[LibreOffice.git] / editeng / source / lookuptree / Trie.cxx
blob6505c00e43f960428bcf5f8a19a041b433eae55d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include <sal/config.h>
12 #include <string_view>
14 #include <editeng/Trie.hxx>
16 namespace editeng
19 /* TrieNode */
21 struct TrieNode final
23 static const int LATIN_ARRAY_SIZE = 26;
25 sal_Unicode mCharacter;
26 bool mMarker;
27 std::vector<std::unique_ptr<TrieNode>> mChildren;
28 std::unique_ptr<TrieNode> mLatinArray[LATIN_ARRAY_SIZE];
30 explicit TrieNode(sal_Unicode aCharacter = '\0');
32 void markWord();
33 TrieNode* findChild(sal_Unicode aCharacter);
34 TrieNode* traversePath(std::u16string_view sPath);
35 void addNewChild(TrieNode* pChild);
36 void collectSuggestions(std::u16string_view sPath, std::vector<OUString>& rSuggestionList);
37 static void collectSuggestionsForCurrentNode(TrieNode* pCurrent, std::u16string_view sPath, std::vector<OUString>& rSuggestionList);
40 TrieNode::TrieNode(sal_Unicode aCharacter) :
41 mCharacter(aCharacter),
42 mMarker(false)
44 for (auto & i : mLatinArray)
46 i = nullptr;
50 void TrieNode::markWord()
52 mMarker = true;
55 void TrieNode::addNewChild(TrieNode* pChild)
57 if (pChild->mCharacter >= 'a' &&
58 pChild->mCharacter <= 'z')
60 mLatinArray[pChild->mCharacter - u'a'].reset(pChild);
62 else
64 mChildren.push_back(std::unique_ptr<TrieNode>(pChild));
68 TrieNode* TrieNode::findChild(sal_Unicode aInputCharacter)
70 if (aInputCharacter >= 'a' &&
71 aInputCharacter <= 'z')
73 return mLatinArray[aInputCharacter - u'a'].get();
76 for(auto const & pCurrent : mChildren)
78 if ( pCurrent->mCharacter == aInputCharacter )
79 return pCurrent.get();
82 return nullptr;
85 void TrieNode::collectSuggestions(std::u16string_view sPath, std::vector<OUString>& rSuggestionList)
87 // first traverse nodes for alphabet characters
88 for (auto const & pCurrent : mLatinArray)
90 if (pCurrent != nullptr)
91 collectSuggestionsForCurrentNode(pCurrent.get(), sPath, rSuggestionList);
94 // traverse nodes for other characters
95 for(auto const & pCurrent : mChildren)
97 if (pCurrent != nullptr)
98 collectSuggestionsForCurrentNode(pCurrent.get(), sPath, rSuggestionList);
102 void TrieNode::collectSuggestionsForCurrentNode(TrieNode* pCurrent, std::u16string_view sPath, std::vector<OUString>& rSuggestionList)
104 OUString aStringPath = sPath + OUStringChar(pCurrent->mCharacter);
105 if(pCurrent->mMarker)
107 rSuggestionList.push_back(aStringPath);
109 // recursively descend tree
110 pCurrent->collectSuggestions(aStringPath, rSuggestionList);
113 TrieNode* TrieNode::traversePath(std::u16string_view sPath)
115 TrieNode* pCurrent = this;
117 for ( const auto aCurrentChar : sPath )
119 pCurrent = pCurrent->findChild(aCurrentChar);
120 if ( pCurrent == nullptr )
121 return nullptr;
124 return pCurrent;
127 /* TRIE */
129 Trie::Trie() :
130 mRoot(new TrieNode())
133 Trie::~Trie()
136 void Trie::insert(std::u16string_view sInputString) const
138 // adding an empty word is not allowed
139 if ( sInputString.empty() )
141 return;
144 // traverse the input string and modify the tree with new nodes / characters
146 TrieNode* pCurrent = mRoot.get();
148 for ( const auto aCurrentChar : sInputString )
150 TrieNode* pChild = pCurrent->findChild(aCurrentChar);
151 if ( pChild == nullptr )
153 TrieNode* pNewNode = new TrieNode(aCurrentChar);
154 pCurrent->addNewChild(pNewNode);
155 pCurrent = pNewNode;
157 else
159 pCurrent = pChild;
163 pCurrent->markWord();
166 void Trie::findSuggestions(std::u16string_view sWordPart, std::vector<OUString>& rSuggestionList) const
168 TrieNode* pNode = mRoot->traversePath(sWordPart);
170 if (pNode != nullptr)
172 pNode->collectSuggestions(sWordPart, rSuggestionList);
176 size_t Trie::size() const
178 if (!mRoot)
179 return 0;
180 std::vector<OUString> entries;
181 mRoot->collectSuggestions(std::u16string_view(), entries);
182 return entries.size();
186 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */