LCOV - code coverage report
Current view: top level - editeng/source/lookuptree - Trie.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 82 0.0 %
Date: 2014-04-14 Functions: 0 15 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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             :  */
       9             : 
      10             : #include <editeng/Trie.hxx>
      11             : 
      12             : namespace editeng
      13             : {
      14             : 
      15             : using namespace std;
      16             : 
      17             : /* TrieNode */
      18             : 
      19             : struct TrieNode
      20             : {
      21             :     static const int LATIN_ARRAY_SIZE = 26;
      22             : 
      23             :     sal_Unicode             mCharacter;
      24             :     bool                    mMarker;
      25             :     std::vector<TrieNode*>  mChildren;
      26             :     TrieNode*               mLatinArray[LATIN_ARRAY_SIZE];
      27             : 
      28             : 
      29             :     TrieNode(sal_Unicode aCharacter = '\0');
      30             :     virtual ~TrieNode();
      31             : 
      32             :     void      markWord();
      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             :     void      collectSuggestionsForCurrentNode(TrieNode* pCurrent, const OUString& sPath, vector<OUString>& rSuggestionList);
      38             : };
      39             : 
      40           0 : TrieNode::TrieNode(sal_Unicode aCharacter) :
      41             :     mCharacter(aCharacter),
      42           0 :     mMarker(false)
      43             : {
      44           0 :     for (int i=0; i<LATIN_ARRAY_SIZE; i++)
      45             :     {
      46           0 :         mLatinArray[i] = NULL;
      47             :     }
      48           0 : }
      49             : 
      50           0 : TrieNode::~TrieNode()
      51             : {
      52           0 :     vector<TrieNode*>::iterator iNode;
      53           0 :     for(iNode = mChildren.begin(); iNode != mChildren.end(); ++iNode)
      54             :     {
      55           0 :         delete *iNode;
      56             :     }
      57             : 
      58           0 :     for (int i=0; i<LATIN_ARRAY_SIZE; i++)
      59             :     {
      60           0 :         delete mLatinArray[i];
      61             :     }
      62           0 : }
      63             : 
      64           0 : void TrieNode::markWord()
      65             : {
      66           0 :     mMarker = true;
      67           0 : }
      68             : 
      69           0 : void TrieNode::addNewChild(TrieNode* pChild)
      70             : {
      71           0 :     if (pChild->mCharacter >= 'a' &&
      72           0 :         pChild->mCharacter <= 'z')
      73             :     {
      74           0 :         mLatinArray[pChild->mCharacter - sal_Unicode('a')] = pChild;
      75             :     }
      76             :     else
      77             :     {
      78           0 :         mChildren.push_back(pChild);
      79             :     }
      80           0 : }
      81             : 
      82           0 : TrieNode* TrieNode::findChild(sal_Unicode aInputCharacter)
      83             : {
      84           0 :     if (aInputCharacter >= 'a' &&
      85             :         aInputCharacter <= 'z')
      86             :     {
      87           0 :         return mLatinArray[aInputCharacter - sal_Unicode('a')];
      88             :     }
      89             : 
      90           0 :     vector<TrieNode*>::iterator iNode;
      91             : 
      92           0 :     for(iNode = mChildren.begin(); iNode != mChildren.end(); ++iNode)
      93             :     {
      94           0 :         TrieNode* pCurrent = *iNode;
      95           0 :         if ( pCurrent->mCharacter == aInputCharacter )
      96           0 :             return pCurrent;
      97             :     }
      98             : 
      99           0 :     return NULL;
     100             : }
     101             : 
     102           0 : void TrieNode::collectSuggestions(const OUString& sPath, vector<OUString>& rSuggestionList)
     103             : {
     104             :     // first traverse nodes for alphabet characters
     105           0 :     for (int i=0; i<LATIN_ARRAY_SIZE; i++)
     106             :     {
     107           0 :         TrieNode* pCurrent = mLatinArray[i];
     108           0 :         if (pCurrent != NULL)
     109           0 :             collectSuggestionsForCurrentNode(pCurrent, sPath, rSuggestionList);
     110             :     }
     111             : 
     112             :     // traverse nodes for other characters
     113           0 :     vector<TrieNode*>::iterator iNode;
     114           0 :     for(iNode = mChildren.begin(); iNode != mChildren.end(); ++iNode)
     115             :     {
     116           0 :         TrieNode* pCurrent = *iNode;
     117           0 :         if (pCurrent != NULL)
     118           0 :             collectSuggestionsForCurrentNode(pCurrent, sPath, rSuggestionList);
     119             :     }
     120           0 : }
     121             : 
     122           0 : void TrieNode::collectSuggestionsForCurrentNode(TrieNode* pCurrent, const OUString& sPath, vector<OUString>& rSuggestionList)
     123             : {
     124           0 :     OUString aStringPath = sPath + OUString(pCurrent->mCharacter);
     125           0 :     if(pCurrent->mMarker)
     126             :     {
     127           0 :         rSuggestionList.push_back(aStringPath);
     128             :     }
     129             :     // recursivly descend tree
     130           0 :     pCurrent->collectSuggestions(aStringPath, rSuggestionList);
     131           0 : }
     132             : 
     133           0 : TrieNode* TrieNode::traversePath(const OUString& sPath)
     134             : {
     135           0 :     TrieNode* pCurrent = this;
     136             : 
     137           0 :     for ( sal_Int32 i = 0; i < sPath.getLength(); i++ )
     138             :     {
     139           0 :         sal_Unicode aCurrentChar = sPath[i];
     140           0 :         pCurrent = pCurrent->findChild(aCurrentChar);
     141           0 :         if ( pCurrent == NULL )
     142           0 :             return NULL;
     143             :     }
     144             : 
     145           0 :     return pCurrent;
     146             : }
     147             : 
     148             : /* TRIE */
     149             : 
     150           0 : Trie::Trie() :
     151           0 :     mRoot(new TrieNode())
     152           0 : {}
     153             : 
     154           0 : Trie::~Trie()
     155           0 : {}
     156             : 
     157           0 : void Trie::insert(const OUString& sInputString) const
     158             : {
     159             :     // adding an empty word is not allowed
     160           0 :     if ( sInputString.isEmpty() )
     161             :     {
     162           0 :         return;
     163             :     }
     164             : 
     165             :     // traverse the input string and modify the tree with new nodes / characters
     166             : 
     167           0 :     TrieNode* pCurrent = mRoot.get();
     168             :     sal_Unicode aCurrentChar;
     169             : 
     170           0 :     for ( sal_Int32 i = 0; i < sInputString.getLength(); i++ )
     171             :     {
     172           0 :         aCurrentChar = sInputString[i];
     173           0 :         TrieNode* pChild = pCurrent->findChild(aCurrentChar);
     174           0 :         if ( pChild == NULL )
     175             :         {
     176           0 :             TrieNode* pNewNode = new TrieNode(aCurrentChar);
     177           0 :             pCurrent->addNewChild(pNewNode);
     178           0 :             pCurrent = pNewNode;
     179             :         }
     180             :         else
     181             :         {
     182           0 :             pCurrent = pChild;
     183             :         }
     184             :     }
     185             : 
     186           0 :     pCurrent->markWord();
     187             : }
     188             : 
     189           0 : void Trie::findSuggestions(const OUString& sWordPart, vector<OUString>& rSuggestionList) const
     190             : {
     191           0 :     TrieNode* pNode = mRoot->traversePath(sWordPart);
     192             : 
     193           0 :     if (pNode != NULL)
     194             :     {
     195           0 :         pNode->collectSuggestions(sWordPart, rSuggestionList);
     196             :     }
     197           0 : }
     198             : 
     199           0 : void Trie::getAllEntries(std::vector<OUString>& entries)
     200             : {
     201           0 :     if (mRoot)
     202             :     {
     203           0 :         mRoot->collectSuggestions(OUString(), entries);
     204             :     }
     205           0 : }
     206             : 
     207             : }
     208             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10