Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <string.h>
- int Z,n,points;
- char command[9], id[9];
- int primeNums[21] = {17,31,67,127,257,521,1031,2053,4099,8191,16381,32771,65537,131071,262147,524287,1048583,2097169,4194319,8388617,10000019};
- int primeHash[16] = {31,137,53,397,23,353,71,139,307,431,7,13,131,11,983,991};
- struct Data{
- char ID[9];
- int val;
- Data(){
- val = -1;
- ID[0] = '\0';
- }
- };
- class HashTable{
- private:
- int numPrime, mElems, mDeads;
- Data *T;
- int hash(char *input, int stage){
- int val = 439;
- for(int j=0;j<8;j++){
- val *= primeHash[(j+stage)%16];
- val += (int)input[j];
- val %= primeNums[numPrime];
- } return val;
- }
- void rehash(Data *newTable, int newSize){
- int indeks;
- for(int i=0;i<primeNums[numPrime];i++){
- if(T[i].val >= 0){
- indeks = this->find(newTable, newSize, T[i].ID, true);
- newTable[indeks].val = T[i].val;
- strcpy(newTable[indeks].ID, T[i].ID);
- }
- }
- delete T; T = newTable; mDeads = 0;
- if(newSize > primeNums[numPrime]) numPrime++;
- }
- int find(Data *table, int size, char *name, bool ins){
- int stage = 0, indeks = hash(name, stage++);
- while((table[indeks].val == -2 && !ins) || (table[indeks].val >= 0 && strcmp(table[indeks].ID, name) != 0)){
- indeks += hash(name, stage++);
- indeks %= primeNums[numPrime];
- } return indeks;
- }
- public:
- HashTable(){
- mDeads = mElems = numPrime = 0;
- T = new Data[primeNums[0]];
- }
- ~HashTable(){
- if(T) delete[] T;
- }
- int Find(){
- int indeks = this->find(T, primeNums[numPrime], id, false);
- if(T[indeks].val >= 0) return T[indeks].val;
- return 0;
- }
- void Insert(){
- if(numPrime < 20 && (mElems/primeNums[numPrime] > 0.7 || (mElems+mDeads)/primeNums[numPrime] > 0.85)) {
- Data *newTable = new Data[primeNums[numPrime+1]];
- rehash(newTable, primeNums[numPrime+1]);
- } else if(mDeads/primeNums[numPrime] > 0.15){
- Data *newTable = new Data[primeNums[numPrime]];
- rehash(newTable, primeNums[numPrime]);
- }
- int indeks = this->find(T, primeNums[numPrime], id, true);
- if(T[indeks].val >= 0) T[indeks].val += points;
- else {
- mElems++; if(T[indeks].val == -2) mDeads--;
- T[indeks].val = points;
- strcpy(T[indeks].ID, id);
- }
- }
- int Delete(){
- int indeks = this->find(T, primeNums[numPrime], id, false), val;
- if(T[indeks].val >= 0){
- val = T[indeks].val;
- T[indeks].val = -2;
- mDeads++;
- return val;
- } return -1;
- }
- };
- int main(){
- HashTable *hashTable = 0;
- scanf("%d", &Z); while(Z--){
- hashTable = new HashTable();
- scanf("%d", &n); while(n--){
- scanf("%s %s", command, id);
- if(command[0] == 'I'){
- scanf("%d", &points);
- hashTable->Insert();
- } else if(command[0] == 'D'){
- points = hashTable->Delete();
- if(points < 0) printf("ERROR\n");
- else printf("%d\n", points);
- } else printf("%d\n", hashTable->Find());
- } delete hashTable;
- } return 0;
- }
Add Comment
Please, Sign In to add comment