Guest User

Untitled

a guest
Jul 19th, 2018
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.96 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <string.h>
  3. int Z,n,points;
  4. char command[9], id[9];
  5. int primeNums[21] = {17,31,67,127,257,521,1031,2053,4099,8191,16381,32771,65537,131071,262147,524287,1048583,2097169,4194319,8388617,10000019};
  6. int primeHash[16] = {31,137,53,397,23,353,71,139,307,431,7,13,131,11,983,991};
  7. struct Data{
  8.       char ID[9];
  9.       int val;
  10.       Data(){
  11.               val = -1;
  12.               ID[0] = '\0';
  13.       }
  14. };
  15. class HashTable{
  16. private:
  17.       int numPrime, mElems, mDeads;
  18.       Data *T;
  19.       int hash(char *input, int stage){
  20.               int val = 439;
  21.               for(int j=0;j<8;j++){
  22.                       val *= primeHash[(j+stage)%16];
  23.                       val += (int)input[j];
  24.                       val %= primeNums[numPrime];
  25.               } return val;
  26.       }
  27.       void rehash(Data *newTable, int newSize){
  28.               int indeks;
  29.               for(int i=0;i<primeNums[numPrime];i++){
  30.                       if(T[i].val >= 0){
  31.                               indeks = this->find(newTable, newSize, T[i].ID, true);
  32.                               newTable[indeks].val = T[i].val;
  33.                               strcpy(newTable[indeks].ID, T[i].ID);
  34.                       }
  35.               }
  36.               delete T; T = newTable; mDeads = 0;
  37.               if(newSize > primeNums[numPrime]) numPrime++;
  38.       }
  39.       int find(Data *table, int size, char *name, bool ins){
  40.               int stage = 0, indeks = hash(name, stage++);
  41.               while((table[indeks].val == -2 && !ins) || (table[indeks].val >= 0 && strcmp(table[indeks].ID, name) != 0)){
  42.                       indeks += hash(name, stage++);
  43.                       indeks %= primeNums[numPrime];
  44.               } return indeks;
  45.       }
  46. public:
  47.       HashTable(){
  48.               mDeads = mElems = numPrime = 0;
  49.               T = new Data[primeNums[0]];
  50.       }
  51.       ~HashTable(){
  52.               if(T) delete[] T;
  53.       }
  54.       int Find(){
  55.               int indeks = this->find(T, primeNums[numPrime], id, false);
  56.               if(T[indeks].val >= 0) return T[indeks].val;
  57.               return 0;
  58.       }
  59.       void Insert(){
  60.               if(numPrime < 20 && (mElems/primeNums[numPrime] > 0.7 || (mElems+mDeads)/primeNums[numPrime] > 0.85)) {
  61.                       Data *newTable = new Data[primeNums[numPrime+1]];
  62.                       rehash(newTable, primeNums[numPrime+1]);
  63.               } else if(mDeads/primeNums[numPrime] > 0.15){
  64.                       Data *newTable = new Data[primeNums[numPrime]];
  65.                       rehash(newTable, primeNums[numPrime]);
  66.               }
  67.               int indeks = this->find(T, primeNums[numPrime], id, true);
  68.               if(T[indeks].val >= 0) T[indeks].val += points;
  69.               else {
  70.                       mElems++; if(T[indeks].val == -2) mDeads--;
  71.                       T[indeks].val = points;
  72.                       strcpy(T[indeks].ID, id);
  73.               }
  74.       }
  75.       int Delete(){
  76.               int indeks = this->find(T, primeNums[numPrime], id, false), val;
  77.               if(T[indeks].val >= 0){
  78.                       val = T[indeks].val;
  79.                       T[indeks].val = -2;
  80.                       mDeads++;
  81.                       return val;
  82.               } return -1;
  83.       }
  84. };
  85. int main(){
  86.       HashTable *hashTable = 0;
  87.       scanf("%d", &Z); while(Z--){
  88.               hashTable = new HashTable();
  89.               scanf("%d", &n); while(n--){
  90.                       scanf("%s %s", command, id);
  91.                       if(command[0] == 'I'){
  92.                               scanf("%d", &points);
  93.                               hashTable->Insert();
  94.                       } else if(command[0] == 'D'){
  95.                               points = hashTable->Delete();
  96.                               if(points < 0) printf("ERROR\n");
  97.                               else printf("%d\n", points);
  98.                       } else printf("%d\n", hashTable->Find());
  99.               } delete hashTable;
  100.       } return 0;
  101. }
Add Comment
Please, Sign In to add comment