예제 #1
0
class TrieNode(object):
    '''
    Contains the information of one node. It contains two lists of the positions
    where the string corresponding to that node is found. One stores only the
    positions of exact matches and the other all words that start with that
    string (match).

    Child maintenance is handled with a minimum list. A new TrieNode is given
    the maximum amount of children (number of acceptable characters).

    self.updateNode(value, exact):
        Adds the value to the value lists of that node. Exact-flag determines
        whether the value is added also to the list of exact matches.
    '''

    def __init__(self, charMapSize, value = '', exact = False):
        """
        Trie node contains two linked lists for its values: one is intended for
        exact matches (it is updated only with exact-flag raised). Upon
        creation, the minimum list type child list is created for that node.
        """
        self.exact = LinkedList()
        self.match = LinkedList()
        if value:
            self.updateNode(value, exact)
        self.children = [None] * charMapSize


    def updateNode(self, position, exact):
        """ Add position info for this object """
        self.match.addLast(position)
        if exact:
            self.exact.addLast(position)
예제 #2
0
class RedBlackNode(object):
    '''
    Contains the information of one branch.
    The node knows its children (le[ft] and ri[ght]), its pa[rent], its color,
    its key and its val[ue]. It also knows if it's empty (end-of-list flag).
    Note that nodes cannot store empty values.

    Nodes know their family through the following methods
    methods:
    grandpa():         return the grandpa node or empty node
    sibling():         return the sibling node
    uncle():           return the uncle node or empty node
    updateNode(val):   Add the val(ue) to this node
    '''

    def __init__(self, str='', val=None, pa=None, red=True):
        """ The node can be empty upon creation (if val is not given) """
        self.pa = pa
        self.le = None #left child
        self.ri = None #right child
        self.red = red
        self.key = str
        self.val = LinkedList()
        if val:
            self.empty = False
            self.updateNode(val)
        else:
            self.empty = True

    def __str__(self):
        """ String representation: return key as string """
        return str(self.key)

    def __repr__(self):
        """ String representation: return key as string """
        return str(self.key)

    def grandpa(self):
        """ Return the parent of a parent or empty node """
        if not self.pa.empty:
            return self.pa.pa
        else:
            return RedBlackNode()

    def sibling(self):
        """ Return the sibling of the node (it must exist) """
        if self == self.pa.le:
            return self.pa.ri
        else:
            return self.pa.le

    def uncle(self):
        """ Return the sibling of the parent or empty node """
        grandpa = self.grandpa()
        if grandpa.empty:
            return RedBlackNode()
        elif grandpa.le == self.pa:
            return grandpa.ri
        else:
            return grandpa.le

    def updateNode(self, value):
        """ Add the value to this node """
        self.val.addLast(value)
예제 #3
0
    def _checkString(self):
        """
        The searc term (which is a string) is searched for these things:
            - operator after another operator
            - operator first or last item in search term
            - words with zero letters after sanitation
            - badly placed parantheses
                - closed paranthesis must come after open paranthesis
                - equal number of open and closed parantheses
        The status property is set to 'ok' if search term is good or to 'bad'
        otherwise.

        Creates also a list telling how deep each paranthesis is in inner
        parantheses (in order to find a matching paranthesis).
        For example:
        0    1  0   2   0   0   0   2  0   0   1 0  1   0   0   0   1  # pVal
        word ( word ( word AND word ) NOT word ) or ( word XOR word )  # words
        """
        self._categorize(self.words)
        self._status = 'ok' # will be set to 'bad' if need be

        itemCount = len(self.types)
        paranthesisList = LinkedList() # queue for paranthesis
        self.pList = [0] * len(self.types)
        pVal = 0
        for index, word in enumerate(self.words):
            if self.types[index] == 'W':
                # Words cannot be empty
                if self.sanitizer.sanitize(word) == '':
                    self._status = 'bad'
                    return
            if self.types[index] == 'P':
                # Words cannot be empty, even if they are 'partial'
                if self.sanitizer.sanitize(word) == '':
                    self._status = 'bad'
                    return

            # store paranthesis in a queue, it must be met by closing paranthesis
            if self.types[index] == '(':
                paranthesisList.addLast('(')
                pVal = pVal + 1 # pVal tells how deep we are in paranthesis
                self.pList[index] = pVal
            if self.types[index] == ')':
                self.pList[index] = pVal
                pVal = pVal - 1 # pVal tells how deep we are in paranthesis
                if paranthesisList.values(): # if we had open paranthesis
                    paranthesisList.removeLast() # remove matching one from queue
                else: # we did not have matching paranthesis
                    self._status = 'bad' # Search term is bad
                    return

            # operation cannot be last term, first term or followed by another
            # operation
            if self.types[index] == 'O':
                if index > 0:
                    if not self.types[index-1] == 'O':
                        pass
                else:
                    self._status = 'bad'
                    return
                if index < itemCount - 1:
                    if not self.types[index+1] == 'O':
                        pass
                else:
                    self._status = 'bad'
                    return

        # We have traversed the words. If we have open paranthesis left, they
        # cannot have matching closed paranthesis, search term is bad
        if paranthesisList.values():
            self._status = 'bad'
            return