1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/.
10 #include <editeng/Trie.hxx>
21 static const int LATIN_ARRAY_SIZE
= 26;
23 sal_Unicode mCharacter
;
25 std::vector
<TrieNode
*> mChildren
;
26 TrieNode
* mLatinArray
[LATIN_ARRAY_SIZE
];
29 TrieNode(sal_Unicode aCharacter
= '\0');
33 TrieNode
* findChild(sal_Unicode aCharacter
);
34 TrieNode
* traversePath(const OUString
& sPath
);
35 void addNewChild(TrieNode
* pChild
);
36 void collectSuggestions(const OUString
& sPath
, std::vector
<OUString
>& rSuggestionList
);
37 static void collectSuggestionsForCurrentNode(TrieNode
* pCurrent
, const OUString
& sPath
, vector
<OUString
>& rSuggestionList
);
40 TrieNode::TrieNode(sal_Unicode aCharacter
) :
41 mCharacter(aCharacter
),
44 for (int i
=0; i
<LATIN_ARRAY_SIZE
; i
++)
46 mLatinArray
[i
] = NULL
;
52 vector
<TrieNode
*>::iterator iNode
;
53 for(iNode
= mChildren
.begin(); iNode
!= mChildren
.end(); ++iNode
)
58 for (int i
=0; i
<LATIN_ARRAY_SIZE
; i
++)
60 delete mLatinArray
[i
];
64 void TrieNode::markWord()
69 void TrieNode::addNewChild(TrieNode
* pChild
)
71 if (pChild
->mCharacter
>= 'a' &&
72 pChild
->mCharacter
<= 'z')
74 mLatinArray
[pChild
->mCharacter
- sal_Unicode('a')] = pChild
;
78 mChildren
.push_back(pChild
);
82 TrieNode
* TrieNode::findChild(sal_Unicode aInputCharacter
)
84 if (aInputCharacter
>= 'a' &&
85 aInputCharacter
<= 'z')
87 return mLatinArray
[aInputCharacter
- sal_Unicode('a')];
90 vector
<TrieNode
*>::iterator iNode
;
92 for(iNode
= mChildren
.begin(); iNode
!= mChildren
.end(); ++iNode
)
94 TrieNode
* pCurrent
= *iNode
;
95 if ( pCurrent
->mCharacter
== aInputCharacter
)
102 void TrieNode::collectSuggestions(const OUString
& sPath
, vector
<OUString
>& rSuggestionList
)
104 // first traverse nodes for alphabet characters
105 for (int i
=0; i
<LATIN_ARRAY_SIZE
; i
++)
107 TrieNode
* pCurrent
= mLatinArray
[i
];
108 if (pCurrent
!= NULL
)
109 collectSuggestionsForCurrentNode(pCurrent
, sPath
, rSuggestionList
);
112 // traverse nodes for other characters
113 vector
<TrieNode
*>::iterator iNode
;
114 for(iNode
= mChildren
.begin(); iNode
!= mChildren
.end(); ++iNode
)
116 TrieNode
* pCurrent
= *iNode
;
117 if (pCurrent
!= NULL
)
118 collectSuggestionsForCurrentNode(pCurrent
, sPath
, rSuggestionList
);
122 void TrieNode::collectSuggestionsForCurrentNode(TrieNode
* pCurrent
, const OUString
& sPath
, vector
<OUString
>& rSuggestionList
)
124 OUString aStringPath
= sPath
+ OUString(pCurrent
->mCharacter
);
125 if(pCurrent
->mMarker
)
127 rSuggestionList
.push_back(aStringPath
);
129 // recursivly descend tree
130 pCurrent
->collectSuggestions(aStringPath
, rSuggestionList
);
133 TrieNode
* TrieNode::traversePath(const OUString
& sPath
)
135 TrieNode
* pCurrent
= this;
137 for ( sal_Int32 i
= 0; i
< sPath
.getLength(); i
++ )
139 sal_Unicode aCurrentChar
= sPath
[i
];
140 pCurrent
= pCurrent
->findChild(aCurrentChar
);
141 if ( pCurrent
== NULL
)
151 mRoot(new TrieNode())
157 void Trie::insert(const OUString
& sInputString
) const
159 // adding an empty word is not allowed
160 if ( sInputString
.isEmpty() )
165 // traverse the input string and modify the tree with new nodes / characters
167 TrieNode
* pCurrent
= mRoot
.get();
168 sal_Unicode aCurrentChar
;
170 for ( sal_Int32 i
= 0; i
< sInputString
.getLength(); i
++ )
172 aCurrentChar
= sInputString
[i
];
173 TrieNode
* pChild
= pCurrent
->findChild(aCurrentChar
);
174 if ( pChild
== NULL
)
176 TrieNode
* pNewNode
= new TrieNode(aCurrentChar
);
177 pCurrent
->addNewChild(pNewNode
);
186 pCurrent
->markWord();
189 void Trie::findSuggestions(const OUString
& sWordPart
, vector
<OUString
>& rSuggestionList
) const
191 TrieNode
* pNode
= mRoot
->traversePath(sWordPart
);
195 pNode
->collectSuggestions(sWordPart
, rSuggestionList
);
199 void Trie::getAllEntries(std::vector
<OUString
>& entries
)
203 mRoot
->collectSuggestions(OUString(), entries
);
208 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */