Cod sursa(job #922743)

Utilizator IoannaPandele Ioana Ioanna Data 22 martie 2013 17:02:36
Problema Hashuri Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 6.42 kb
#include <fstream>
#include <string>
#include <sstream>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <cassert>

using namespace std;

ifstream in("hashuri.in");
ofstream out("hashuri.out");
template <class type>
class HashTable {
  private:
    int *h1;
    int *h2;
    unsigned int size;
    unsigned int prime;
    unsigned int a1,a2,b1,b2;
    unsigned int FNV_offset_basis;
    unsigned int FNV_prime;
    unsigned int Convert(const type&);
    unsigned int FNV(const string&);
  public:

  HashTable(unsigned int);
  void Init();
  void DeleteElement(const type&);
  bool InsertElement(const unsigned int&);
  int FindElement(const type&);
  unsigned int HashFunction1(const unsigned int&);
  unsigned int HashFunction2(const unsigned int&);
  bool GenerateFunctions();
  HashTable& operator > (const type&);  //Stergere
  HashTable& operator < (const type&);  //Adaugare
  HashTable& operator <= (const type&); //Interogare
  HashTable Pointer();

  ~HashTable();
};


template <class type> unsigned int HashTable<type>::FNV(const string &value) {
   unsigned int int_value,size;
   char byte;
   int_value = FNV_offset_basis;
   size = value.size();
   for (int i = 0; i < size; ++i) {
        byte = value[i];
        int_value = int_value ^ byte;
        int_value = int_value * FNV_prime;
   }
   return int_value;
}

template <class type> unsigned int HashTable<type>::Convert(const type &value) {
  ostringstream string_str;
  string_str<<value;
  return FNV(string_str.str());
}

template <class type> HashTable <type>::HashTable (unsigned int sz){
  size = sz;
  h1 = new int[sz];
  h2 = new int[sz];
  memset(h1,0,size*sizeof(int));
  memset(h2,0,size*sizeof(int));
  prime=1000000009;
  FNV_offset_basis = 2166136261U;
  FNV_prime = 16777619;
  GenerateFunctions();
}

template <class type> void HashTable <type>::Init() {
  memset(h1,0,size*sizeof(int));
  memset(h2,0,size*sizeof(int));
  GenerateFunctions();
}

template <class type> HashTable <type>::~HashTable() {
  delete[] h1;
  delete[] h2;
}

template <class type> HashTable<type> HashTable<type>::Pointer() {
  return *this;
}

template <class type> void HashTable <type>::DeleteElement(const type &value){
  unsigned int int_value = Convert(value);
  unsigned int location = FindElement(value);
  if (h1[location] == int_value){
    h1[location] = 0;
    }
  else h2[location] = 0;
}

template <class type> unsigned int HashTable <type>::HashFunction1(const unsigned int &value) {
  return (((long long)a1 * value + b1)%prime)%size;
}

template <class type> unsigned int HashTable <type>::HashFunction2(const unsigned int &value) {
  return (((long long)a2 * value + b2)%prime)%size;
}

template <class type> int HashTable <type>::FindElement(const type &value) {
  unsigned int location1,location2;
  unsigned int int_value = Convert(value);
  location1 = HashFunction1(int_value);
  location2 = HashFunction2(int_value);
  if (h1[location1] == int_value){
    return location1;
  } else if (h2[location2] == int_value){
    return location2;
  }
  return -1;
}

template <class type> HashTable<type>& HashTable <type>::operator > (const type &value) {
  DeleteElement(value);
  return *this;
}

template <class type> bool HashTable <type>::GenerateFunctions(){
  a1 = rand() % size;
  a2 = rand() % size;
  b1 = rand() % size;
  b2 = rand() % size;
  return true;
}

template <class type> bool HashTable <type>::InsertElement(const unsigned int &value) {
  unsigned int temporary_value = value;
  unsigned int location;
  unsigned int aux;
  int choose_table = 1;
  do {
    if (choose_table == 1) {
      location = HashFunction1(temporary_value);
      if (h1[location]) {
        aux = h1[location];
        h1[location] = temporary_value;
        temporary_value = aux;
      } else {
        h1[location] = temporary_value;
        return true;
      }
    } else {
      location = HashFunction2(temporary_value);
      if (h2[location]) {
        aux = h2[location];
        h2[location] = temporary_value;
        temporary_value = aux;
      } else {
        h2[location] = temporary_value;
        return true;
      }
    }
    choose_table = -choose_table;
  }
  while (temporary_value !=value || choose_table == -1);
  return false;
}

template <class type> HashTable<type>& HashTable<type>::operator <= (const type &value) {
  if (FindElement(value)!=-1) out<<"1\n";
  else {
    out<<"0\n";
  }
  return *this;
}

template <class type> HashTable<type>& HashTable<type>::operator < (const type &value) {
  unsigned int int_value = Convert(value);
  bool rehash_flag = InsertElement(int_value);
  if (!rehash_flag){
    int *copy_h1;
    int *copy_h2;
    copy_h1 = new int[size];
    copy_h2 = new int[size];
    memcpy(copy_h1,h1,sizeof(h1));
    memcpy(copy_h2,h2,sizeof(h2));
    bool insert_flag = true;

    do{
      do {
        Init();

        insert_flag = true;
        for (int i = 0; i<size && insert_flag; ++i) {
          if (copy_h1[i]) {
            if (!InsertElement(copy_h1[i]))
              insert_flag = false;
          }
          if (copy_h2[i]) {
            if (!InsertElement(copy_h2[i]))
            insert_flag = false;
          }
        }
      } while (!insert_flag);
    } while (!InsertElement(int_value));
    delete[] copy_h1;
    delete[] copy_h2;
  }

  return *this;
}



void solve() {

  HashTable <int> table(1000000);

  srand(time(NULL));

  int number_of_operations;
  int operation,element;
 // table = table < 5 <= 5 >5 <=5 <=7;
  //table = table < 5.2 <= 5.2 >5.2 <= 5.3 <= 7;

  in>>number_of_operations;
  for (int i = 1;i <= number_of_operations; ++i) {
    in>>operation>>element;
    switch (operation) {
      case 1: {
          if (table.FindElement(element) == -1) {
              table = table < element;
            /*while (!table.InsertElement(element)) {
              while (!table.Rehash()){}*/
            }
          break;}
      case 2:{
          if (table.FindElement(element) != -1) table = table > element;
          break;}
      case 3:{
          table = table <= element;
         /* if (table.FindElement(element) != -1) {
            out<<"1\n";
          } else {
            out<<"0\n";
          }*/
          break;}
      default: {
        assert(false);
      }
    }
  }

}

int main() {
  solve();
  return 0;
}