Beispiel #1
0
class BloomFilter:
    def __init__(self, size=10):
        # DO NOT EDIT THIS CONSTRUCTOR
        self.size = size
        self.array = FixedSizeArray(size)
        for i in range(0, size):
            self.array.set(i, False)

    # Adds an element to the bloom filter using three hash functions.
    def add_elem(self, elem):
        # raise NotImplementedError
        hash1 = cs5112_hash1(elem) % self.size
        hash2 = cs5112_hash2(elem) % self.size
        hash3 = cs5112_hash3(elem) % self.size
        for j in [hash1, hash2, hash3]:
            self.array.set(j, True)

    # Returns False if the given element is was definitely not added to the
    # filter. Returns True if it's possible that the element was added to the
    # filter (but not necessarily certain).
    def check_membership(self, elem):
        # raise NotImplementedError
        hash1 = cs5112_hash1(elem) % self.size
        hash2 = cs5112_hash2(elem) % self.size
        hash3 = cs5112_hash3(elem) % self.size
        counter = 0
        for k in [hash1, hash2, hash3]:
            if self.array.get(k):
                counter += 1
        if counter == 0:
            return False
        else:
            return True
Beispiel #2
0
class BloomFilter:
  def __init__(self, size=10):
    # DO NOT EDIT THIS CONSTRUCTOR
    self.size = size
    self.array = FixedSizeArray(size)
    for i in range(0, size):
      self.array.set(i, False)

  # Adds an element to the bloom filter using three hash functions.
  def add_elem(self, elem):    
    index_to_add_h1 = cs5112_hash1(elem) % self.size
    self.array.set(index_to_add_h1, True)
        
    index_to_add_h2 = cs5112_hash2(elem) % self.size
    self.array.set(index_to_add_h2, True)
       
    index_to_add_h3 = cs5112_hash3(elem) % self.size
    self.array.set(index_to_add_h3, True)
    
    return
    
    

  # Returns False if the given element is was definitely not added to the
  # filter. Returns True if it's possible that the element was added to the
  # filter (but not necessarily certain).
  def check_membership(self, elem):
    index_h1 = cs5112_hash1(elem) % self.size
    index_h2 = cs5112_hash2(elem) % self.size
    index_h3 = cs5112_hash3(elem) % self.size
    
    return(self.array.get(index_h1) and self.array.get(index_h2) and self.array.get(index_h3))
Beispiel #3
0
 def _resize_array(self):
     new_array_size = 2 * self.array_size
     new_array = FixedSizeArray(new_array_size)
     for i in range(self.array_size):
         if self.array.get(i) is None or self.array.get(i)[2]:
             continue
         new_hash_index = cs5112_hash1(
             self.array.get(i)[0]) % new_array_size
         while new_array.get(
                 new_hash_index
         ) is not None:  # for a new array, we do not consider deleted case
             new_hash_index = (new_hash_index + 1) % new_array_size
         new_array.set(new_hash_index, self.array.get(i))
     self.array = new_array
     self.array_size = new_array_size
Beispiel #4
0
 def _resize_array(self):
   new_array_size = 2 * self.array_size
   new_array = FixedSizeArray(new_array_size)
   for i in range(self.array_size):
     if self.array.get(i) is None:
       continue
     node = self.array.get(i)
     while node is not None:
       new_index = cs5112_hash1(node.get_value()[0]) % new_array_size
       new_node = new_array.get(new_index)
       if new_node is None:
         new_array.set(new_index, SLLNode(node.get_value()))
       else:
         while new_node.get_next() is not None:
           new_node = new_node.get_next()
         new_node.set_next(SLLNode(node.get_value()))
   self.array = new_array
   self.array_size = new_array_size
class BloomFilter:
    def __init__(self, size=10):
        # DO NOT EDIT THIS CONSTRUCTOR
        self.size = size
        self.array = FixedSizeArray(size)
        for i in range(0, size):
            self.array.set(i, False)

    # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute
    # the positions that we are setting in the fixed size array using modulo operation.
    def add_elem(self, elem):
        #TODO: YOUR CODE HERE, delete the line below and implement accordingly
        raise NotImplementedError

    # Returns False if the given element was definitely not added to the filter.
    # Returns True if it's possible that the element was added to the filter.
    def check_membership(self, elem):
        #TODO: YOUR CODE HERE, delete the line below and implement accordingly
        raise NotImplementedError
class BloomFilter:
  def __init__(self, size=10):
    # DO NOT EDIT THIS CONSTRUCTOR
    self.size = size
    self.array = FixedSizeArray(size)
    for i in range(0, size):
      self.array.set(i, False)

  # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute
  # the positions that we are setting in the fixed size array using modulo operation.
  def add_elem(self, elem):
    #TODO: YOUR CODE HERE, delete the line below and implement accordingly
    hash_1 = cs5112_hash1(elem)
    hash_1_res_rightmost = hash_1 % self.size
    self.array.set(hash_1_res_rightmost, True)

    hash_2 = cs5112_hash2(elem)
    hash_2_res_rightmost = hash_2 % self.size
    self.array.set(hash_2_res_rightmost, True)

    hash_3 = cs5112_hash3(elem)
    hash_3_res_rightmost = hash_3 % self.size
    self.array.set(hash_3_res_rightmost, True)

    #hash_res = cs5112_hash3(cs5112_hash2(cs5112_hash1(elem)))
    #hash_res_rightmost = hash_res % 10
    
    # while (hash_res > 0):
    #   hash_res_rightmost = hash_res % 10
    #   self.array.set(hash_res_rightmost, True)
    #   hash_res = hash_res / 10

  # Returns False if the given element was definitely not added to the filter. 
  # Returns True if it's possible that the element was added to the filter.
  def check_membership(self, elem):
    #TODO: YOUR CODE HERE, delete the line below and implement accordingly
    hash_1 = cs5112_hash1(elem)
    hash_1_res_rightmost = hash_1 % self.size
    bool1 = self.array.get(hash_1_res_rightmost)

    hash_2 = cs5112_hash2(elem)
    hash_2_res_rightmost = hash_2 % self.size
    bool2 = self.array.get(hash_2_res_rightmost)

    hash_3 = cs5112_hash3(elem)
    hash_3_res_rightmost = hash_3 % self.size
    bool3 = self.array.get(hash_3_res_rightmost)

    if (bool1 and bool2 and bool3):
      return True

    return False
Beispiel #7
0
class BloomFilter:
    def __init__(self, size=10):
        # DO NOT EDIT THIS CONSTRUCTOR
        self.size = size
        self.array = FixedSizeArray(size)
        for i in range(0, size):
            self.array.set(i, False)

    # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute
    # the positions that we are setting in the fixed size array using modulo operation.
    def add_elem(self, elem):
        p1 = cs5112_hash1(elem) % self.size
        p2 = cs5112_hash2(elem) % self.size
        p3 = cs5112_hash3(elem) % self.size
        self.array.set(p1, True)
        self.array.set(p2, True)
        self.array.set(p3, True)

    # Returns False if the given element was definitely not added to the filter.
    # Returns True if it's possible that the element was added to the filter.
    def check_membership(self, elem):
        p1 = cs5112_hash1(elem) % self.size
        p2 = cs5112_hash2(elem) % self.size
        p3 = cs5112_hash3(elem) % self.size
        if not self.array.get(p1) or not self.array.get(
                p2) or not self.array.get(p3):
            return False

        return True
class BloomFilter:
    def __init__(self, size=10):
        # DO NOT EDIT THIS CONSTRUCTOR
        self.size = size
        self.array = FixedSizeArray(size)
        for i in range(0, size):
            self.array.set(i, False)

    # Adds an element to the bloom filter using three hash functions.
    def add_elem(self, elem):
        index1 = cs5112_hash1(elem) % self.size
        index2 = cs5112_hash2(elem) % self.size
        index3 = cs5112_hash3(elem) % self.size

        self.array.set(index1, True)
        self.array.set(index2, True)
        self.array.set(index3, True)

    # Returns False if the given element is was definitely not added to the
    # filter. Returns True if it's possible that the element was added to the
    # filter (but not necessarily certain).
    def check_membership(self, elem):
        index1 = cs5112_hash1(elem) % self.size
        index2 = cs5112_hash2(elem) % self.size
        index3 = cs5112_hash3(elem) % self.size

        value1 = self.array.get(index1)
        value2 = self.array.get(index2)
        value3 = self.array.get(index3)

        if not value1:
            return False
        elif not value2:
            return False
        elif not value3:
            return False
        else:
            return True
class BloomFilter:
  def __init__(self, size=10):
    # DO NOT EDIT THIS CONSTRUCTOR
    self.size = size
    self.array = FixedSizeArray(size)
    for i in range(0, size):
      self.array.set(i, False)

  # Adds an element to the bloom filter using three hash functions.
  def add_elem(self, elem):
    # If elem is None, raise an Exception
    if (elem == None):
      raise ValueError("Key can't be None")
    # Calculate the hashes for a given element.
    h1 = cs5112_hash1(elem) % self.size
    h2 = cs5112_hash2(elem) % self.size
    h3 = cs5112_hash3(elem) % self.size
    
    # Set True at h1, h2, and h3.
    self.array.set(h1, True)
    self.array.set(h2, True)
    self.array.set(h3, True)

  # Returns False if the given element was definitely not added to the
  # filter. Returns True if it's possible that the element was added to the
  # filter (but not necessarily certain).
  def check_membership(self, elem):
    # If elem is None, raise an Exception
    if (elem == None):
      raise ValueError("Key can't be None")
    # Calculate the hashes for a given element.
    h1 = cs5112_hash1(elem) % self.size
    h2 = cs5112_hash2(elem) % self.size
    h3 = cs5112_hash3(elem) % self.size
    
    return (self.array.get(h1) and self.array.get(h2) and self.array.get(h3))
        
Beispiel #10
0
class BloomFilter:
    def __init__(self, size=10):
        # DO NOT EDIT THIS CONSTRUCTOR
        self.size = size
        self.array = FixedSizeArray(size)
        for i in range(0, size):
            self.array.set(i, False)

    # To add an element to the bloom filter, use each of the k=3 hash functions we provided and compute
    # the positions that we are setting in the fixed size array using modulo operation.
    def add_elem(self, elem):
        index1 = cs5112_hash1(elem) % self.size
        index2 = cs5112_hash2(elem) % self.size
        index3 = cs5112_hash3(elem) % self.size
        print(index1, index2, index3)

        # set indices to True
        self.array.set(index1, True)
        self.array.set(index2, True)
        self.array.set(index3, True)

    # Returns False if the given element was definitely not added to the filter.
    # Returns True if it's possible that the element was added to the filter.
    def check_membership(self, elem):
        index1 = cs5112_hash1(elem) % self.size
        index2 = cs5112_hash2(elem) % self.size
        index3 = cs5112_hash3(elem) % self.size
        print(index1, index2, index3)

        value1 = self.array.get(index1)
        value2 = self.array.get(index2)
        value3 = self.array.get(index3)
        print(value1, value2, value3)

        # if all these indices are set to True in the bit array -> probably present (True)
        result = value1 and value2 and value3
        return result
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):
        # if key or value is None, raise an Exception
        if (key == None or value == None):
            raise ValueError("Neither Key nor Value can be None")

        # Get the hash value and take the modulus
        hashval = cs5112_hash1(key) % self.array_size

        # If there is nothing at that entry in the array, create the first node and inc count
        if (self.array.get(hashval) == None):
            newNode = SLLNode((key, value))
            self.array.set(hashval, newNode)
            self.item_count += 1
        else:
            # If something already exists, iterate through and see if any match the key
            node = self.array.get(hashval)
            prevNode = None

            while (node != None):
                # If so, update the value and don't change the count
                if (node.get_value()[0] == key):
                    node.set_value((key, value))
                    return
                prevNode = node
                node = node.get_next()

            # Else at the end add the node and inc the count
            newNode = SLLNode((key, value), None)
            prevNode.set_next(newNode)
            self.item_count += 1

        # If the load factor now exceeds the limit, resize
        if ((float(self.item_count) / self.array_size) > self.load_factor):
            self._resize_array()

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):
        # If key is None, raise an Exception
        if (key == None):
            raise ValueError("Key can't be None")

        # Get hash value and mod it
        hashval = cs5112_hash1(key) % self.array_size
        node = self.array.get(hashval)

        # While 'node' isn't None, search through
        while (node != None):
            if (node.get_value()[0] == key):
                return node.get_value()[1]
            node = node.get_next()

        # Else return None
        return None

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):
        # If key is None, raise an Exception
        if (key == None):
            raise ValueError("Key can't be None")

        # Get hash value and mod it
        hashval = cs5112_hash1(key) % self.array_size

        node = self.array.get(hashval)
        # Can't remove it if it doesn't exist
        if (node == None):
            return None

        # If it is the first element of the linked list, set that pointer to the next
        if (node.get_value()[0] == key):
            self.array.set(hashval, node.get_next())
            self.item_count -= 1
            return node.get_value()[1]

        prevNode = node
        node = node.get_next()

        # While 'node' isn't None, search through
        while (node != None):
            # If it is found further down the list, set the previous node's
            # pointer to the next node and return the value
            if (node.get_value()[0] == key):
                prevNode.set_next(node.get_next())
                self.item_count -= 1
                return node.get_value()[1]
            prevNode = node
            node = node.get_next()

        # Else return None
        return None

    # Returns the number of elements in the hash table.
    def size(self):
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):
        tupList = []
        # Iterate through all of the items in the previous array and add to a list
        for i in range(self.array_size):
            node = self.array.get(i)
            while (node != None):
                tupList.append(node.get_value())
                node = node.get_next()

        # Replace self.array with the new array
        self.array = FixedSizeArray(self.array_size * 2)
        self.array_size *= 2
        self.item_count = 0

        # Iterate through the list of tuples and add them back
        for (k, v) in tupList:
            self.insert(k, v)

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS FUNCTION
        return self.array


# Helper print function to investigate inner workings of structure
# def printArray(self):
#   print("[", end = '')
#   for i in range(self.array_size):
#     node = self.array.get(i)
#     if (node == None):
#       print("None, ", end='')
#     while (node != None):
#       print(node.get_value(),end='')
#       node = node.get_next()
#       if (node != None):
#         print("->",end='')
#       else:
#         print(", ",end='')
#   print("]")
#   return
Beispiel #12
0
class HashTable:
  def __init__(self, initial_size=10, load_factor=.75):
    # DO NOT EDIT THIS CONSTRUCTOR
    if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
      raise Exception("size must be greater than zero, and load factor must be between 0 and 1")
    self.array_size = initial_size
    self.load_factor = load_factor
    self.item_count = 0
    self.array = FixedSizeArray(initial_size)

  # Inserts the `(key, value)` pair into the hash table, overwriting any value
  # previously associated with `key`.
  # Note: Neither `key` nor `value` may be None (an exception will be raised)
  def insert(self, key=None, value=None):

    try:
      if key is None or value is None:
        raise TypeError

      ind = cs5112_hash1(key) % self.array.size
      head = self.array.get(ind)

      while head != None:

        if head.get_value()[0] == key:
          head.set_value((key, value))
          return

        head = head.get_next()

      self.item_count += 1
      # print("SIZE after insert = " + str(self.item_count))

      head = self.array.get(ind)
      new_node = SLLNode((key,value))

      new_node.set_next(head)
      self.array.set(ind, new_node)

      if (self.item_count / self.array.size) > self.load_factor:
        temp_arr = self.array
        self._resize_array()
        self.item_count = 0

        for i in range(temp_arr.size):

          oldhead = temp_arr.get(i)
          while oldhead != None:
            self.insert(oldhead.get_value()[0], oldhead.get_value()[1])
            oldhead = oldhead.get_next()

    except TypeError:
      print('Key and/or value cannot be None!')

  # Returns the value associated with `key` in the hash table, or None if no
  # such value is found.
  # Note: `key` may not be None (an exception will be raised)
  def get(self, key=None):

    try:
      if key is None:
        raise TypeError

      ind = cs5112_hash1(key) % self.array.size
      head = self.array.get(ind)

      while head != None:
        if head.get_value()[0] == key:
          return head.get_value()[1]

        head = head.get_next()

      return None

    except TypeError:
      print('Key cannot be None!')



  # Removes the `(key, value)` pair matching the given `key` from the map, if it
  # exists. If such a pair exists in the map, the return value will be the value
  # that was removed. If no such value exists, the method will return None.
  # Note: `key` may not be None (an exception will be raised)
  def remove(self, key):

    try:
      if key is None:
        raise TypeError

      ind = cs5112_hash1(key) % self.array_size
      head = self.array.get(ind)
      prev = None

      print("HEAD = " + str(head))

      while head != None:
        if head.get_value()[0] == key:
          break

        prev = head
        head = head.get_next()

      if not head:
        return None

      self.item_count -= 1

      if prev != None:
        prev.set_next(head.get_next())
      else:
        self.array.set(ind, head.get_next())

      return head.get_value()[1]

    except TypeError:
      print('Key cannot be None!')


  # Returns the number of elements in the hash table.
  def size(self):
    return self.item_count

  # Internal helper function for resizing the hash table's array once the ratio
  # of stored mappings to array size exceeds the specified load factor.
  def _resize_array(self):

    self.array = FixedSizeArray(2 * self.array.size)
    self.array_size *= 2

  # Internal helper function for accessing the array underlying the hash table.
  def _get_array(self):
    # DO NOT EDIT THIS FUNCTION
    return self.array
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):

        # check loading factor, if over, resize

        if self.load_factor <= (self.item_count / self.array_size):
            self._resize_array()

        # hash the key
        hash_ind = cs5112_hash1(key) % self.array_size

        # loop until an empty index found
        while self.array.get(hash_ind) != None and self.array.get(
                hash_ind) != 'removed':

            # if you hash and get back the key, then update the value
            if self.array.get(
                    hash_ind)[0] == key:  # check the first entry in the tuple
                self.array.set(hash_ind, (key, value))

            # check hash of next index
            hash_ind = (hash_ind + 1) % self.array_size

        # loop broken, found None elem, so set it
        self.array.set(hash_ind, (key, value))
        self.item_count += 1

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):

        # hash the key
        hash_ind = cs5112_hash1(key) % self.array_size

        # loop through non empty cells
        while self.array.get(hash_ind) != None:

            elem = self.array.get(hash_ind)  # get the elem

            # if the elem is not removed, check it's key, value
            # else, just continue searching
            if elem != 'removed':

                # if you hash and get back the key
                if elem[0] == key:  # check key in tuple
                    return elem[1]  # second entry is value

            # get hash of next index
            hash_ind = (hash_ind + 1) % self.array_size

        # if looped through and no match, return None
        return None

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):

        # hash the key
        hash_ind = cs5112_hash1(key) % self.array_size

        # loop through non empty cells
        while self.array.get(hash_ind) != None:

            elem = self.array.get(hash_ind)

            # if you hash and get back the key
            if elem[0] == key:  # check the first entry in the tuple
                self.array.set(hash_ind, 'removed')
                self.item_count -= 1  # decrement
                return elem

            # get hash of next index
            hash_ind = (hash_ind + 1) % self.array_size

        # if looped through and no match, return None
        return None

    # Returns the number of elements in the hash table.
    def size(self):
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):

        # store old array here temp.
        temp = []

        # loop through old array
        for ind in range(self.array_size):
            # if entry is not empty, save it in temp
            if self.array.get(ind) and self.array.get(ind) != 'removed':
                key, value = self.array.get(ind)  # retrieve the elem
                temp.append((key, value))

        self.array_size *= 2  # double size
        self.item_count = 0  # reset count to 0

        # make new array
        self.array = FixedSizeArray(self.array_size)

        # loop through temp array and reinsert into new array
        for elem in temp:
            key, value = elem  # unpack it
            self.insert(key, value)

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS METHOD
        return self.array
Beispiel #14
0
class HashTable:
  def __init__(self, initial_size=10, load_factor=.75):
    # DO NOT EDIT THIS CONSTRUCTOR
    if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
      raise Exception("size must be greater than zero, and load factor must be between 0 and 1")
    self.array_size = initial_size
    self.load_factor = load_factor
    self.item_count = 0
    self.array = FixedSizeArray(initial_size)

  # Inserts the `(key, value)` pair into the hash table, overwriting any value
  # previously associated with `key`.
  # Note: Neither `key` nor `value` may be None (an exception will be raised)
  def insert(self, key, value):
    # YOUR CODE HERE
    if key == None:
      raise Exception('Key cannot be None!')
    if value == None:
      raise Exception('Value cannot be None!')
    k = cs5112_hash1(key)%self.array_size
    pointer = self.array.get(k)
    node = SLLNode((key,value))
    if pointer==None:
      self.array.set(k, node)
    else:
      while pointer.get_next()!= None:
        if pointer.get_value()[0]== key:
          pointer.set_value((key,value))
          return
        pointer = pointer.get_next()
      pointer.set_next(node)
    self.item_count += 1
    # if self.item_count/self.array_size >= self.load_factor:
    #   self._resize_array()
    
    
  # Returns the value associated with `key` in the hash table, or None if no
  # such value is found.
  # Note: `key` may not be None (an exception will be raised)
  def get(self, key):
    # YOUR CODE HERE
    if key == None:
      raise Exception('Key cannot be None!')
    k = cs5112_hash1(key)%self.array_size
    start = self.array.get(k)
    while start != None and start.get_value()!= None:
      if start.get_value()[0] == key:
        return start.get_value()[1]
      start = start.get_next()
    return None
        
  # Removes the `(key, value)` pair matching the given `key` from the map, if it
  # exists. If such a pair exists in the map, the return value will be the value
  # that was removed. If no such value exists, the method will return None.
  # Note: `key` may not be None (an exception will be raised)
  def remove(self, key):
    # YOUR CODE HERE
    # REWRITE!!!
    if key == None:
      raise Exception('Key cannot be None!')
    k = cs5112_hash1(key)%self.array_size
    prev = curr = self.array.get(k)
    if curr != None:
      while curr.get_next()!= None:
        if curr.get_value()[0]== key:
          if curr.get_next()==None:
            prev.set_next(None)
          else:
            prev.set_next(curr.get_next())
          self.item_count-=1
          return curr.get_value()
        else:
          prev = curr
          curr = curr.get_next()
    else:
      return None

  # Returns the number of elements in the hash table.
  def size(self):
    # YOUR CODE HERE
    # raise NotImplementedError()
    return self.item_count

  # Internal helper function for resizing the hash table's array once the ratio
  # of stored mappings to array size exceeds the specified load factor.
  def _resize_array(self):
    # YOUR CODE HERE
    orgsize = self.array_size
    orgarray = self.array

    self.array_size *= 2
    self.array = FixedSizeArray(self.array_size)
    self.item_count = 0

    for i in range(orgsize):
      orgelem = orgarray.get(i)
      if orgelem != None:
        self.insert(orgelem[0],orgelem[1])


  # Internal helper function for accessing the array underlying the hash table.
  def _get_array(self):
    # DO NOT EDIT THIS FUNCTION
    return self.array
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)
        self.total_item_count = 0  # includes cells that have been flagged for removal

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):
        if key is None or value is None:
            raise Exception("key, value cannot be None")

        h = cs5112_hash1(key) % self.array_size
        in_arr = self.get(key) is not None
        if not in_arr:
            self.item_count += 1
            self.total_item_count += 1
        ind = self._find_usable_index(key, h, in_arr)
        self.array.set(ind, (key, value, True))

        if self._get_current_load() >= self.load_factor:
            self._resize_array()

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):
        if key is None:
            raise Exception("Key cannot be None")

        h = cs5112_hash1(key) % self.array_size
        for i in xrange(self.array_size):
            index = (h + i) % self.array_size

            # if we run into None, it isn't in the array
            if self.array.get(index) is None:
                return None
            # found it
            k, v, in_use = self.array.get(index)
            if k == key and in_use:
                return v
        return None

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):
        if key is None:
            raise Exception("Key cannot be None")

        h = cs5112_hash1(key) % self.array_size
        for i in xrange(self.array_size):
            index = (h + i) % self.array_size

            # if we run into None, it isn't in the array
            if self.array.get(index) is None:
                return None

            # if we found it and it's in use, remove it
            k, v, in_use = self.array.get(index)
            if k == key and in_use:
                self.array.set(index, (k, v, False))
                self.item_count -= 1
                return v
        return None

    # Returns the number of elements in the hash table.
    def size(self):
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):
        self.array_size *= 2
        self.item_count = 0
        self.total_item_count = 0
        prev_arr = self.array
        self.array = FixedSizeArray(self.array_size)
        for i in xrange(self.array_size / 2):
            if prev_arr.get(i) is None:
                continue
            k, v, in_use = prev_arr.get(i)
            if in_use:
                self.insert(k, v)

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS METHOD
        return self.array

    def _get_current_load(self):
        return float(self.total_item_count) / self.array_size

    # finds the index that can be used to insert an element in the array
    def _find_usable_index(self, key, start_index, in_array):
        # potentially iterate over entire array
        for i in xrange(self.array_size):
            ind = (start_index + i) % self.array_size
            # if we find an empty cell, we know we can use it (and in_array must be False)
            if self.array.get(ind) is None:
                return ind

            k, _, in_use = self.array.get(ind)
            if not in_array:
                # we've found a cell that isn't empty but also isn't being used
                if not in_use:
                    self.total_item_count -= 1  # we added to total item count assuming we weren't overwriting a value
                    return ind
            else:
                # we've found the original cell
                if key == k:
                    return ind
        return -1
Beispiel #16
0
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):

        if self.load_factor <= (self.item_count / self.array_size):
            self._resize_array()

        # create a new SLL node
        new_node = SLLNode((key, value))  # pass tuple as value

        hash_id = cs5112_hash1(key) % self.array_size
        curr_node = self.array.get(hash_id)

        # if hashed array elem is empty, set the elem to the new node
        if not curr_node:
            self.array.set(hash_id, new_node)
            self.item_count += 1
            return  # done, return

        override = False

        # otherwise, loop through linked list until the end
        while curr_node.get_next(
        ):  # when the next node is None, you've reached the end

            # if the key in curr node == key passed, override the value
            if curr_node.get_value()[0] == key:
                curr_node.set_value((key, value))
                override = True

            curr_node = curr_node.get_next()

        # if you're not overriding, you're adding the new node to the end
        if not override:
            curr_node.set_next(new_node)
            self.item_count += 1

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):

        hash_id = cs5112_hash1(key) % self.array_size
        curr_node = self.array.get(hash_id)

        # loop until the end
        while curr_node:

            node_key, node_value = curr_node.get_value()

            # check if the key in the node is the same as the key passed in
            if key == node_key:  # key in first entry of the tuple
                return node_value
            curr_node = curr_node.get_next()

        return None

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):

        hash_id = cs5112_hash1(key) % self.array_size
        front_node = self.array.get(hash_id)
        curr_node = front_node
        prev_node = None
        saved_value = None

        # if empty, return None
        if not curr_node:
            return None

        # otherwise, loop until elem is found, and set the prev next node to curr's next node
        while curr_node:

            node_key, node_value = curr_node.get_value()  # unpack the value

            # check if keys match
            if node_key == key:

                # if prev, then item not in the front
                if prev_node:
                    prev_node.set_next(curr_node.get_next())  #

                else:  # item is in the front, so set hash elem to the elem after curr node
                    self.array.set(hash_id, curr_node.get_next())

                self.item_count -= 1  # decrement count
                return node_value  # return saved value

            # update pointers
            prev_node = curr_node
            curr_node = curr_node.get_next()

        return None  # not found if reaches here

    # Returns the number of elements in the hash table.
    def size(self):
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):

        # create new array
        new_array = FixedSizeArray(self.array_size * 2)

        temp_array = []  # temp array

        # loop through fixed array current elems
        for elem in self.array.items:

            # temporarily store all elements into list
            if elem:
                temp_array.append(elem)

        self.array = new_array  # set array to new empty array
        self.array_size = self.array_size * 2  # set new size variable
        self.item_count = 0  # reset item count

        # reinsert each elem in temp array into new FixedSizedArray
        for elem in temp_array:

            # need to loop through entire linked list and reinsert each node
            while elem:

                key, value = elem.get_value()  # retrieve the tuple
                self.insert(key, value)  # insert into new array
                elem = elem.get_next()

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS FUNCTION
        return self.array
Beispiel #17
0
class HashTable:
  def __init__(self, initial_size=10, load_factor=.75):
    # DO NOT EDIT THIS CONSTRUCTOR
    if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
      raise Exception("size must be greater than zero, and load factor must be between 0 and 1")
    self.array_size = initial_size
    self.load_factor = load_factor
    self.item_count = 0
    self.array = FixedSizeArray(initial_size)

  # Inserts the `(key, value)` pair into the hash table, overwriting any value
  # previously associated with `key`.
  # Note: Neither `key` nor `value` may be None (an exception will be raised)
  def insert(self, key, value):
    self.item_count += 1
    if (self.item_count * 1.0 / self.array_size) > self.load_factor:
      self._resize_array()
    index = cs5112_hash1(key) % self.array_size
    if self.array.get(index) is None:
      self.array.set(index, SLLNode((key, value)))
    else:
      node = self.array.get(index)
      prevNode = node
      while node is not None:
        if node.get_value()[0] == key:
          # overwrite
          node.set_value((key, value))
          self.item_count -= 1
          return
        prevNode = node
        node = node.get_next()
      prevNode.set_next(SLLNode)

  # Returns the value associated with `key` in the hash table, or None if no
  # such value is found.
  # Note: `key` may not be None (an exception will be raised)
  def get(self, key):
    index = cs5112_hash1(key)
    node = self.array.get(index)
    while node is not None:
      if node.get_value()[0] == key:
        return node.get_value()[1]
      node = node.get_next()
    return None


  # Removes the `(key, value)` pair matching the given `key` from the map, if it
  # exists. If such a pair exists in the map, the return value will be the value
  # that was removed. If no such value exists, the method will return None.
  # Note: `key` may not be None (an exception will be raised)
  def remove(self, key):
    index = cs5112_hash1(key)
    node = self.array.get(index)
    prevNode = None
    while node is not None:
      if node.get_value()[0] == key:
      # delete this node
        if prevNode is None:
          self.array.set(index, node.get_next())
        else:
          prevNode.set_next(node.get_next())
        self.item_count -= 1
        return node.get_value()[1]
      prevNode = node
      node = node.get_next()
    return None

  # Returns the number of elements in the hash table.
  def size(self):
    return self.item_count

  # Internal helper function for resizing the hash table's array once the ratio
  # of stored mappings to array size exceeds the specified load factor.
  def _resize_array(self):
    new_array_size = 2 * self.array_size
    new_array = FixedSizeArray(new_array_size)
    for i in range(self.array_size):
      if self.array.get(i) is None:
        continue
      node = self.array.get(i)
      while node is not None:
        new_index = cs5112_hash1(node.get_value()[0]) % new_array_size
        new_node = new_array.get(new_index)
        if new_node is None:
          new_array.set(new_index, SLLNode(node.get_value()))
        else:
          while new_node.get_next() is not None:
            new_node = new_node.get_next()
          new_node.set_next(SLLNode(node.get_value()))
    self.array = new_array
    self.array_size = new_array_size

  # Internal helper function for accessing the array underlying the hash table.
  def _get_array(self):
    # DO NOT EDIT THIS FUNCTION
    return self.array
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):
        # YOUR CODE HERE
        if key == None:
            raise Exception('Key cannot be None!')
        if value == None:
            raise Exception('Value cannot be None!')
        h = cs5112_hash1(key) % self.array_size
        while self.array.get(h) != None:
            if self.array.get(h)[0] == key:
                self.array.set(h, (key, value))
                return
            h += 1
            if h == self.array_size - 1:
                self._resize_array()
                h = cs5112_hash1(key) % self.array_size
        self.array.set(h, (key, value))
        if self.item_count / self.array_size >= self.load_factor:
            self._resize_array()

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):
        # YOUR CODE HERE
        if key == None:
            raise Exception('Key cannot be None!')
        h = cs5112_hash1(key) % self.array_size
        while self.array.get(h) != None:
            if self.array.get(h)[0] == key:
                return self.array.get(h)[1]
            else:
                h += 1

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):
        # YOUR CODE HERE
        if key == None:
            raise Exception('Key cannot be None!')
        p = cs5112_hash1(key) % self.array_size
        ret = self._get_array().get(p)
        while ret == 'd' or ret and ret[0] != key:
            p += 1
            ret = self._get_array().get(p)
        if not ret:
            return False
        else:
            self._get_array().set(p, 'd')
            return True

    # Returns the number of elements in the hash table.
    def size(self):
        # YOUR CODE HERE
        return self.array_size

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):
        # YOUR CODE HERE
        orgsize = self.array_size
        orgarray = self.array

        self.array_size *= 2
        self.array = FixedSizeArray(self.array_size)
        self.item_count = 0

        for i in range(orgsize):
            orgelem = orgarray.get(i)
            if orgelem != None:
                self.insert(orgelem[0], orgelem[1])

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS METHOD
        return self.array
Beispiel #19
0
class HashTable:
  def __init__(self, initial_size=10, load_factor=.75):
    # DO NOT EDIT THIS CONSTRUCTOR
    if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
      raise Exception("size must be greater than zero, and load factor must be between 0 and 1")
    self.array_size = initial_size
    self.load_factor = load_factor
    self.item_count = 0
    self.array = FixedSizeArray(initial_size)

  # Inserts the `(key, value)` pair into the hash table, overwriting any value
  # previously associated with `key`.
  # Note: Neither `key` nor `value` may be None (an exception will be raised)
  def insert(self, key, value):

    if key==None or value==None:
      raise Exception

    if (self.item_count/self.array_size)>=self.load_factor:
      self._resize_array()
      

    bucket= cs5112_hash1(key) % self.array_size
    new_node=SLLNode((key, value))
    pointer= self.array.get(bucket)

    if not pointer:
      self.array.set(bucket, new_node)
      self.item_count+=1
      return

    else:

      while pointer.get_next():

        if pointer.get_value()[0]== key:
          pointer.set_value=((key, value))
          return
        pointer=pointer.get_next()

      if pointer.get_value()[0]== key:
          pointer.set_value=((key, value))
          return

      else:
        pointer.set_next(new_node)
        self.item_count+=1
        return
      



  # Returns the value associated with `key` in the hash table, or None if no
  # such value is found.
  # Note: `key` may not be None (an exception will be raised)
  def get(self, key):

    if key== None:
      raise Exception

    bucket= cs5112_hash1(key) % self.array_size

    if not self.array.get(bucket):
      return None

    pointer= self.array.get(bucket)

    while pointer.get_next():

      if pointer.get_value()[0]== key:
        return pointer.get_value()[1]
      pointer=pointer.get_next()

    if pointer.get_value()[0]== key:
      return pointer.get_value()[1]

    else: 
      return None


  # Removes the `(key, value)` pair matching the given `key` from the map, if it
  # exists. If such a pair exists in the map, the return value will be the value
  # that was removed. If no such value exists, the method will return None.
  # Note: `key` may not be None (an exception will be raised)
  def remove(self, key):

    if key== None:
      raise Exception

    bucket= cs5112_hash1(key) % self.array_size

    if not self.array.get(bucket):
      return None

    pointer= self.array.get(bucket)

    if pointer.get_value()[0]== key:
      val= pointer.get_value()[1]
      self.array.set(bucket, pointer.get_next())
      self.item_count-=1
      return val

    while pointer.get_next():

      if pointer.get_next().get_value()[0]== key:
        val= pointer.get_next().get_value()[1]
        pointer.set_next((pointer.get_next().get_next()))
        self.item_count-=1
        return val

      pointer=pointer.get_next()

    return None


    

  # Returns the number of elements in the hash table.
  def size(self):
    # YOUR CODE HERE
    return self.item_count

  # Internal helper function for resizing the hash table's array once the ratio
  # of stored mappings to array size exceeds the specified load factor.
  def _resize_array(self):

    ht= HashTable(self.array_size*2, self.load_factor)
    index=0

    while index<self.array_size:
      
      if not self.array.get(index):
        index+=1

      else:
        pointer= self.array.get(index)

        while pointer!= None:
          key= pointer.get_value()[0]
          value= pointer.get_value()[1]
          ht.insert(key, value)
          pointer = pointer.get_next()
        index+=1

    self.array_size=ht.array_size
    self.array=ht.array

  # Internal helper function for accessing the array underlying the hash table.
  def _get_array(self):
    # DO NOT EDIT THIS FUNCTION
    return self.array
Beispiel #20
0
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):
        # Raise exception if either key or value is None
        if (key == None or value == None):
            raise ValueError("Neither Key nor Value can be None")

        h = cs5112_hash1(key) % self.array_size

        # If nothing exists at this location, just insert, increment
        if self.array.get(h) == None:
            self.array.set(h, (key, value))
            self.item_count += 1
        else:
            # Iterate through the next elements until you reach a None, update if you see the same key
            while self.array.get(h) != None:
                if self.array.get(h)[0] == key:
                    self.array.set(h, (key, value))
                    return
                h = (h + 1) % self.array_size

            # Insert value at this None
            self.array.set(h, (key, value))
            self.item_count += 1

        # If the load factor now exceeds the limit, resize
        if ((float(self.item_count) / self.array_size) > self.load_factor):
            self._resize_array()

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):
        # If key is None, raise an Exception
        if (key == None):
            raise ValueError("Key can't be None")

        h = cs5112_hash1(key) % self.array_size

        if self.array.get(h) == None:
            return None

        while self.array.get(h) != None:
            if self.array.get(h)[0] == key:
                return self.array.get(h)[1]
            h = (h + 1) % self.array_size

        return None

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):
        # If key is None, raise an Exception
        if (key == None):
            raise ValueError("Key can't be None")

        h = cs5112_hash1(key) % self.array_size
        result = None

        # If None at that hash table value can return immedietely
        if self.array.get(h) == None:
            return None

        # Iterate through array to check for key matches
        while self.array.get(h) != None:
            if self.array.get(h)[0] == key:
                result = self.array.get(h)[1]
                self.array.set(h, None)
                self.item_count -= 1
                break
            h = (h + 1) % self.array_size

        # If result is found, need to reinsert next
        if result != None:
            tupList = []
            curr = (h + 1) % self.array_size

            while (self.array.get(curr) != None):
                tupList.append(self.array.get(curr))
                self.array.set(curr, None)
                self.item_count -= 1
                curr = (curr + 1) % self.array_size

            for (k, v) in tupList:
                self.insert(k, v)

        return result

    # Returns the number of elements in the hash table.
    def size(self):
        # YOUR CODE HERE
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):
        # YOUR CODE HERE
        self.array_size *= 2
        oldArray = self.array
        self.array = FixedSizeArray(self.array_size)

        for i in range(0, oldArray.size):
            if oldArray.get(i) != None:
                h = cs5112_hash1(oldArray.get(i)[0]) % self.array_size

                while self.array.get(h) is not None:
                    h = (h + 1) % self.array_size

                self.array.set(h, (oldArray.get(i)[0], oldArray.get(i)[1]))

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS METHOD
        return self.array

    # def printArray(self):
    #   print("[", end = '')
    #   for i in range(self.array_size):
    #     print(str(self.array.get(i))+", ", end = '')
    #   print("]")
    #   return
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):
        if key is None or value is None:
            raise Exception("key and value cannot be None")

        in_arr = self.get(key) is not None
        if not in_arr:
            self.item_count += 1

        ind = cs5112_hash1(key) % self.array_size
        cur_list = self.array.get(ind)
        if cur_list is None:
            self.array.set(ind, SLLNode((key, value), None))
        else:
            # see if it's already in the list
            for n in self._iterate_list(cur_list):
                k, _ = n.get_value()
                if k is key:
                    n.set_value((key, value))
                    return
            # it isn't already in the list
            self._list_get_last(cur_list).set_next(SLLNode((key, value), None))

        if self._get_current_load() >= self.load_factor:
            self._resize_array()

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):
        if key is None:
            raise Exception("key cannot be None")

        ind = cs5112_hash1(key) % self.array_size
        cur_list = self.array.get(ind)
        # list doesn't exist, value must not be stored
        if cur_list is None:
            return None

        # search through list
        for n in self._iterate_list(cur_list):
            k, v = n.get_value()
            if k == key:
                return v
        # value was not found
        return None

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):
        if key is None:
            raise Exception("Key cannot be None")

        ind = cs5112_hash1(key) % self.array_size
        cur_list = self.array.get(ind)
        ret_val = None

        # if the list is None, we definitely don't have the value stored
        if cur_list is None:
            return None

        # first item in linked list
        if cur_list.get_value()[0] == key:
            ret_val = cur_list.get_value()[1]
            self.item_count -= 1
            self.array.set(ind, cur_list.get_next())
        else:
            # search through the list to see if the key is in it
            for n in self._iterate_list(cur_list):
                if n == None:  # it isn't in the list
                    return None
                next_node = n.get_next()

                if next_node == None:
                    return None
                k, v = next_node.get_value()
                if k == key:  # found the key, so store the value
                    ret_val = v
                    self.item_count -= 1
                    n.set_next(next_node.get_next())
                    return ret_val

        return ret_val

    # Returns the number of elements in the hash table.
    def size(self):
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):
        self.array_size *= 2
        self.item_count = 0
        prev_arr = self.array
        self.array = FixedSizeArray(self.array_size)

        for i in xrange(self.array_size / 2):
            if prev_arr.get(i) is None:
                continue

            cur_list = prev_arr.get(i)
            for n in self._iterate_list(cur_list):
                k, v = n.get_value()
                self.insert(k, v)

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS FUNCTION
        return self.array

    def _get_current_load(self):
        return float(self.item_count) / self.array_size

    # generator for linked lists
    def _iterate_list(self, first_node):
        node = first_node
        while node != None:
            yield node
            node = node.get_next()

    def _list_get_last(self, node):
        while node.get_next() != None:
            node = node.get_next()
        return node
Beispiel #22
0
class HashTable:
    def __init__(self, initial_size=10, load_factor=.75):
        # DO NOT EDIT THIS CONSTRUCTOR
        if (initial_size < 0) or (load_factor <= 0) or (load_factor > 1):
            raise Exception(
                "size must be greater than zero, and load factor must be between 0 and 1"
            )
        self.array_size = initial_size
        self.load_factor = load_factor
        self.item_count = 0
        self.array = FixedSizeArray(initial_size)

    # ============ We mark a flag for DELETION ============

    # Inserts the `(key, value)` pair into the hash table, overwriting any value
    # previously associated with `key`.
    # Note: Neither `key` nor `value` may be None (an exception will be raised)
    def insert(self, key, value):
        # first search
        self.item_count += 1
        if (self.item_count * 1.0 / self.array_size) > self.load_factor:
            self._resize_array()
        hash_key = cs5112_hash1(key) % self.array_size
        #condtion: hash_key is not empty
        while self.array.get(hash_key) is not None:
            # condition 1: rewrite, same key and haven't been deleted
            if self.array.get(
                    hash_key)[0] == key and not self.array.get(hash_key)[2]:
                self.item_count -= 1
                self.array.set(hash_key, (key, value, False))
                return
            #condition 2: rewrite, same key but been deleted
            elif self.array.get(hash_key)[0] == key and self.array.get(
                    hash_key)[2]:
                self.array.set(hash_key, (key, value, False))
                return
            #condition 3: empty space, but still need to search for the rest
            elif self.array.get(hash_key)[2]:
                self.array.set(hash_key, (key, value, False))
                hash_key = (hash_key + 1) % self.array_size
                while self.array.get(hash_key) is not None:
                    if self.array.get(hash_key)[0] == key:
                        self.item_count -= 1
                        self.array.set(
                            hash_key, (key, self.array.get(hash_key)[1], True))
                    return
            hash_key = (hash_key + 1) % self.array_size
        self.array.set(hash_key, (key, value, False))
        return
        # while self.array.get(hash_key) is not None\
        #         and self.array.get(hash_key)[0] != key\
        #         and not self.array.get(hash_key)[2]:  # not deleted
        #   hash_key = (hash_key + 1) % self.array_size
        # # if there is an vacant array in the middle, just reset it
        # # if previously key is associated, just replace it
        # if self.array.get(hash_key) is not None and \
        #     self.array.get(hash_key)[0] == key:  # overwrite case
        #     self.item_count -= 1
        #     self.array.set(hash_key, (key, value, False))
        #     return  # accelerate
        # self.array.set(hash_key, (key, value, False))
        # # Delete previously entry with the same key
        # hash_key = (hash_key + 1) % self.array_size
        # while self.array.get(hash_key) is not None:
        #   if self.array.get(hash_key)[0] == key:
        #     self.array.set(hash_key, (key, value, True))
        #     break
        #   hash_key = (hash_key + 1) % self.array_size

    # Returns the value associated with `key` in the hash table, or None if no
    # such value is found.
    # Note: `key` may not be None (an exception will be raised)
    def get(self, key):
        hash_key = cs5112_hash1(key) % self.array_size
        while self.array.get(hash_key) is not None:
            if not self.array.get(hash_key)[2] and self.array.get(
                    hash_key)[0] == key:
                return self.array.get(hash_key)[1]
            hash_key += 1
        return None
        # Removed start var since we will not search the whole array
        # for the worst case hash(value) = constant:
        # since the load factor < 1, there must be some None in the array [never has elements]
        # start = hash_key
        # while self.array.get(hash_key)[0] != key:  # TODO: if the entry is None, it will cause Exception
        #   hash_key += 1
        #   if hash_key == start:
        #     return None
        # return self.array.get(hash_key)[1]

    # Removes the `(key, value)` pair matching the given `key` from the map, if it
    # exists. If such a pair exists in the map, the return value will be the value
    # that was removed. If no such value exists, the method will return None.
    # Note: `key` may not be None (an exception will be raised)
    def remove(self, key):
        if self.item_count == 0:
            return None  # add a corner case to accelerate
        # self.item_count -= 1  # TODO: if non-exist, count should not -1
        # search for the entry first
        hash_key = cs5112_hash1(key) % self.array_size
        while self.array.get(hash_key) is not None:
            if not self.array.get(hash_key)[2] and self.array.get(
                    hash_key)[0] == key:
                value = self.array.get(hash_key)[1]
                # mark the entry as deleted
                self.array.set(hash_key, (key, value, True))
                self.item_count -= 1
                return value
        return None
        # start = hash_key
        # while self.array.get(hash_key) is None or self.array.get(hash_key)[0] != key:
        #   # TODO: time complexity is O(array_size) which could be optimized at least to O(array_size * load_factor)
        #   hash_key = (hash_key + 1) % self.array_size
        #   if hash_key == start:
        #     return None
        # return_val = self.array.get(hash_key)[1]
        # self.array.set(hash_key, None)
        # return return_val

    # Returns the number of elements in the hash table.
    def size(self):
        return self.item_count

    # Internal helper function for resizing the hash table's array once the ratio
    # of stored mappings to array size exceeds the specified load factor.
    def _resize_array(self):
        new_array_size = 2 * self.array_size
        new_array = FixedSizeArray(new_array_size)
        for i in range(self.array_size):
            if self.array.get(i) is None or self.array.get(i)[2]:
                continue
            new_hash_index = cs5112_hash1(
                self.array.get(i)[0]) % new_array_size
            while new_array.get(
                    new_hash_index
            ) is not None:  # for a new array, we do not consider deleted case
                new_hash_index = (new_hash_index + 1) % new_array_size
            new_array.set(new_hash_index, self.array.get(i))
        self.array = new_array
        self.array_size = new_array_size

    # Internal helper function for accessing the array underlying the hash table.
    def _get_array(self):
        # DO NOT EDIT THIS METHOD
        return self.array
Beispiel #23
0
class BloomFilter:
  def __init__(self, size=10):
    # DO NOT EDIT THIS CONSTRUCTOR
    self.size = size
    self.array = FixedSizeArray(size)
    for i in range(0, size):
      self.array.set(i, False)

  # Adds an element to the bloom filter using three hash functions.
  def add_elem(self, elem):

    h_val1 = cs5112_hash1(elem) % 10
    init_h_val2 = cs5112_hash2(elem)
    h_val2 = init_h_val2 % 10
    init_h_val3 = cs5112_hash3(elem)
    h_val3 = init_h_val3 % 10

    i = 1
    while h_val2 == h_val1 and i < len(str(init_h_val2)):
        # h_val2 = int(cs5112_hash2(elem) % (10 ** (i + 1)) / 10 ** i)
        h_val2 = init_h_val2 % (10 ** (i + 1)) // 10 ** i
        i += 1

    j = 1
    while (h_val3 == h_val1 or h_val3 == h_val2) and j < len(str(init_h_val3)):
        # h_val3 = int(cs5112_hash3(elem) % (10 ** (j + 1)) / 10 **j)
        h_val3 = init_h_val3 % (10 ** (j + 1)) // 10 ** j
        j += 1

    self.array.set(h_val1, True)
    self.array.set(h_val2, True)
    self.array.set(h_val3, True)

  # Returns False if the given element is was definitely not added to the
  # filter. Returns True if it's possible that the element was added to the
  # filter (but not necessarily certain).
  def check_membership(self, elem):

    h_val1 = cs5112_hash1(elem) % 10
    init_h_val2 = cs5112_hash2(elem)
    h_val2 = init_h_val2 % 10
    init_h_val3 = cs5112_hash3(elem)
    h_val3 = init_h_val3 % 10

    i = 1
    while h_val2 == h_val1 and i < len(str(init_h_val2)):
        # h_val2 = int(cs5112_hash2(elem) % (10 ** (i + 1)) / 10 ** i)
        h_val2 = init_h_val2 % (10 ** (i + 1)) // 10 ** i
        i += 1

    j = 1
    while (h_val3 == h_val1 or h_val3 == h_val2) and j < len(str(init_h_val3)):
        # h_val3 = int(cs5112_hash3(elem) % (10 ** (j + 1)) / 10 **j)
        h_val3 = init_h_val3 % (10 ** (j + 1)) // 10 ** j
        j += 1

    for ind in [h_val1, h_val2, h_val3]:
        if not self.array.get(ind):
            return False

    return True