Bump version to 4.1-6
[LibreOffice.git] / editeng / source / lookuptree / Trie.cxx
blob30ee0be0769f1e086c9e6976dab180fe3d6bf0f3
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 <editeng/Trie.hxx>
12 namespace editeng
15 using namespace std;
17 /* TrieNode */
19 TrieNode::TrieNode(sal_Unicode aCharacter) :
20 mCharacter(aCharacter),
21 mMarker(false)
23 for (int i=0; i<LATIN_ARRAY_SIZE; i++)
25 mLatinArray[i] = NULL;
29 TrieNode::~TrieNode()
31 vector<TrieNode*>::iterator iNode;
32 for(iNode = mChildren.begin(); iNode != mChildren.end(); iNode++)
34 delete *iNode;
37 for (int i=0; i<LATIN_ARRAY_SIZE; i++)
39 delete mLatinArray[i];
43 void TrieNode::markWord()
45 mMarker = true;
48 void TrieNode::addNewChild(TrieNode* pChild)
50 if (pChild->mCharacter >= sal_Unicode('a') &&
51 pChild->mCharacter <= sal_Unicode('z'))
53 mLatinArray[pChild->mCharacter - sal_Unicode('a')] = pChild;
55 else
57 mChildren.push_back(pChild);
61 TrieNode* TrieNode::findChild(sal_Unicode aInputCharacter)
63 if (aInputCharacter >= sal_Unicode('a') &&
64 aInputCharacter <= sal_Unicode('z'))
66 return mLatinArray[aInputCharacter - sal_Unicode('a')];
69 vector<TrieNode*>::iterator iNode;
71 for(iNode = mChildren.begin(); iNode != mChildren.end(); iNode++)
73 TrieNode* pCurrent = *iNode;
74 if ( pCurrent->mCharacter == aInputCharacter )
75 return pCurrent;
78 return NULL;
81 void TrieNode::collectSuggestions(OUString sPath, vector<OUString>& rSuggestionList)
83 // first traverse nodes for alphabet characters
84 for (int i=0; i<LATIN_ARRAY_SIZE; i++)
86 TrieNode* pCurrent = mLatinArray[i];
87 if (pCurrent != NULL)
89 OUString aStringPath = sPath + OUString(pCurrent->mCharacter);
90 if(pCurrent->mMarker)
91 rSuggestionList.push_back(aStringPath);
92 // recursivly traverse tree
93 pCurrent->collectSuggestions(aStringPath, rSuggestionList);
97 // traverse nodes for other characters
98 vector<TrieNode*>::iterator iNode;
99 for(iNode = mChildren.begin(); iNode != mChildren.end(); iNode++)
101 TrieNode* pCurrent = *iNode;
102 if (pCurrent != NULL)
104 OUString aStringPath = sPath + OUString(pCurrent->mCharacter);
105 if(pCurrent->mMarker)
106 rSuggestionList.push_back(aStringPath);
107 // recursivly traverse tree
108 pCurrent->collectSuggestions(aStringPath, rSuggestionList);
113 TrieNode* TrieNode::traversePath(OUString sPath)
115 TrieNode* pCurrent = this;
117 for ( sal_Int32 i = 0; i < sPath.getLength(); i++ )
119 sal_Unicode aCurrentChar = sPath[i];
120 pCurrent = pCurrent->findChild(aCurrentChar);
121 if ( pCurrent == NULL )
122 return NULL;
125 return pCurrent;
128 /* TRIE */
130 Trie::Trie()
132 mRoot = new TrieNode();
135 Trie::~Trie()
137 delete mRoot;
140 void Trie::insert(OUString sInputString) const
142 // adding an empty word is not allowed
143 if ( sInputString.isEmpty() )
145 return;
148 // traverse the input string and modify the tree with new nodes / characters
150 TrieNode* pCurrent = mRoot;
151 sal_Unicode aCurrentChar;
153 for ( sal_Int32 i = 0; i < sInputString.getLength(); i++ )
155 aCurrentChar = sInputString[i];
156 TrieNode* pChild = pCurrent->findChild(aCurrentChar);
157 if ( pChild == NULL )
159 TrieNode* pNewNode = new TrieNode(aCurrentChar);
160 pCurrent->addNewChild(pNewNode);
161 pCurrent = pNewNode;
163 else
165 pCurrent = pChild;
169 pCurrent->markWord();
172 void Trie::findSuggestions(OUString sWordPart, vector<OUString>& rSuggesstionList) const
174 TrieNode* pNode = mRoot->traversePath(sWordPart);
176 if (pNode != NULL)
178 pNode->collectSuggestions(sWordPart, rSuggesstionList);
183 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */