Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
Longest Increasing Subsequence - main.py

main.py

Caricato da: Lumo
Scarica il programma completo

  1. import operator
  2.  
  3. def _bisect_left(array, element, lo = 0, hi = None, comp = None):
  4.     if comp is None:
  5.         comp = operator.lt
  6.  
  7.     if hi is None:
  8.         hi = len(array)
  9.  
  10.     while lo < hi:
  11.         middle = (lo+hi) // 2
  12.  
  13.         if not comp(array[middle], element):
  14.             hi = middle
  15.         else:
  16.             lo = middle+1
  17.  
  18.     return hi    
  19.            
  20. class longest_subsequence_result(object):
  21.     def __init__(self, sequence, positions, endingElements, ordering):
  22.  
  23.         self.length = len(endingElements) - 1
  24.        
  25.         if self.length > 0:
  26.             self.positions_ = self.computePositions(positions, endingElements)
  27.             self.elements_  = self.computeElements(sequence)
  28.         else:
  29.             self.positions_ = []
  30.             self.elements_ = []
  31.  
  32.         self.ordering = ordering
  33.        
  34.  
  35.     def __len__(self):
  36.         return self.length
  37.  
  38.     def computePositions(self, positions, endingElements):
  39.         positions_ = [None] * self.length
  40.  
  41.         scan = endingElements[self.length]
  42.         for i in reversed(xrange(0,self.length)):
  43.             positions_[i] = scan
  44.             scan = positions[positions_[i]]
  45.  
  46.         return positions_
  47.  
  48.     def computeElements(self, sequence):
  49.         return [ sequence[index] for index in self.positions_ ]              
  50.  
  51.     def __len__(self):
  52.         return self._length
  53.  
  54.     def get_ordering():
  55.         return self.ordering
  56.  
  57.     def get_elements(self):
  58.         return self.elements_
  59.  
  60.     def get_positions(self):
  61.         return self.positions_
  62.        
  63. def longest_subsequence(sequence, comp = None):
  64.     if not sequence:
  65.         return longest_subsequence_result( None, None, [], comp )        
  66.  
  67.     if comp is None:
  68.         comp = operator.lt
  69.    
  70.     endingElements = [None]
  71.     previousElements = []
  72.    
  73.     for index, element in enumerate(sequence):
  74.         insertionPos = _bisect_left(endingElements, element, lo = 1, comp=lambda a, b: comp(sequence[a],b))
  75.  
  76.         if insertionPos == len(endingElements):            
  77.             endingElements.append(index)            
  78.         else:
  79.             endingElements[ insertionPos ] = index
  80.            
  81.         previousElements.append( endingElements[ insertionPos - 1 ] )          
  82.    
  83.     return longest_subsequence_result( sequence, previousElements, endingElements, comp )
  84.  
  85. if __name__ ==  "__main__":
  86.     array = [0,1,4,6,3,2,3,4,5,1,23,34,12,-1,23,54,1,2]
  87.     print longest_subsequence( array ).get_elements()
  88.     print longest_subsequence( array, operator.le ).get_elements()
  89.     print longest_subsequence( array, operator.gt ).get_elements()