Cod sursa(job #1182523)

Utilizator AlexandruValeanuAlexandru Valeanu AlexandruValeanu Data 6 mai 2014 19:05:49
Problema Hashuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 12.56 kb
#include <cstdio>
#include <set>
#include <cstdlib>
#include <ctime>

using namespace std;

        #ifndef LinkedList_H
        #define LinkedList_H


        #include <iostream>    // For NULL

        // List class
        //
        // CONSTRUCTION: with no initializer
        // Access is via ListItr class
        //
        // ******************PUBLIC OPERATIONS*********************
        // boolean isEmpty( )     --> Return true if empty; else false
        // void makeEmpty( )      --> Remove all items
        // ListItr zeroth( )      --> Return position to prior to first
        // ListItr first( )       --> Return first position
        // void insert( x, p )    --> Insert x after current iterator position p
        // void remove( x )       --> Remove x
        // ListItr find( x )      --> Return position that views x
        // ListItr findPrevious( x )
        //                        --> Return position prior to x
        // ******************ERRORS********************************
        // No special errors

        template <class Object>
        class List;     // Incomplete declaration.

        template <class Object>
        class ListItr;     // Incomplete declaration.

        template <class Object>
        class ListNode
        {
            ListNode( const Object & theElement = Object( ), ListNode * n = NULL )
              : element( theElement ), next( n ) { }

            Object   element;
            ListNode *next;

            friend class List<Object>;
            friend class ListItr<Object>;
        };


        template <class Object>
        class List
        {
          public:
            List( );
            List( const List & rhs );
            ~List( );

            bool isEmpty( ) const;
            void makeEmpty( );
            ListItr<Object> zeroth( ) const;
            ListItr<Object> first( ) const;
            void insert( const Object & x, const ListItr<Object> & p );
            ListItr<Object> find( const Object & x ) const;
            ListItr<Object> findPrevious( const Object & x ) const;
            void remove( const Object & x );

            const List & operator=( const List & rhs );

          private:
            ListNode<Object> *header;
        };


        // ListItr class; maintains "current position"
        //
        // CONSTRUCTION: Package friendly only, with a ListNode
        //
        // ******************PUBLIC OPERATIONS*********************
        // bool isPastEnd( )      --> True if past end position in list
        // void advance( )        --> Advance (if not already null)
        // Object retrieve        --> Return item in current position

        template <class Object>
        class ListItr
        {
          public:
            ListItr( ) : current( NULL ) { }
            bool isPastEnd( ) const
              { return current == NULL; }
            void advance( )
              { if( !isPastEnd( ) ) current = current->next; }
            const Object & retrieve( ) const
              {
                return current->element; }

          private:
            ListNode<Object> *current;    // Current position

            ListItr( ListNode<Object> *theNode )
              : current( theNode ) { }

            friend class List<Object>; // Grant access to constructor
        };


        #endif


        /**
         * Construct the list
         */
        template <class Object>
        List<Object>::List( )
        {
            header = new ListNode<Object>;
        }

        /**
         * Copy constructor
         */
        template <class Object>
        List<Object>::List( const List<Object> & rhs )
        {
            header = new ListNode<Object>;
            *this = rhs;
        }

        /**
         * Destructor
         */
        template <class Object>
        List<Object>::~List( )
        {
            makeEmpty( );
            delete header;
        }

        /**
         * Test if the list is logically empty.
         * return true if empty, false otherwise.
         */
        template <class Object>
        bool List<Object>::isEmpty( ) const
        {
            return header->next == NULL;
        }

        /**
         * Make the list logically empty.
         */
        template <class Object>
        void List<Object>::makeEmpty( )
        {
            while( !isEmpty( ) )
                remove( first( ).retrieve( ) );
        }

        /**
         * Return an iterator representing the header node.
         */
        template <class Object>
        ListItr<Object> List<Object>::zeroth( ) const
        {
            return ListItr<Object>( header );
        }

        /**
         * Return an iterator representing the first node in the list.
         * This operation is valid for empty lists.
         */
        template <class Object>
        ListItr<Object> List<Object>::first( ) const
        {
            return ListItr<Object>( header->next );
        }

        /**
         * Insert item x after p.
         */
        template <class Object>
        void List<Object>::insert( const Object & x, const ListItr<Object> & p )
        {
            if( p.current != NULL )
                p.current->next = new ListNode<Object>( x, p.current->next );
        }

        /**
         * Return iterator corresponding to the first node containing an item x.
         * Iterator isPastEnd if item is not found.
         */
        template <class Object>
        ListItr<Object> List<Object>::find( const Object & x ) const
        {
/* 1*/      ListNode<Object> *itr = header->next;

/* 2*/      while( itr != NULL && itr->element != x )
/* 3*/          itr = itr->next;

/* 4*/      return ListItr<Object>( itr );
        }

        /**
         * Return iterator prior to the first node containing an item x.
         */
        template <class Object>
        ListItr<Object> List<Object>::findPrevious( const Object & x ) const
        {
/* 1*/      ListNode<Object> *itr = header;

/* 2*/      while( itr->next != NULL && itr->next->element != x )
/* 3*/          itr = itr->next;

/* 4*/      return ListItr<Object>( itr );
        }

        /**
         * Remove the first occurrence of an item x.
         */
        template <class Object>
        void List<Object>::remove( const Object & x )
        {
            ListItr<Object> p = findPrevious( x );

            if( p.current->next != NULL )
            {
                ListNode<Object> *oldNode = p.current->next;
                p.current->next = p.current->next->next;  // Bypass deleted node
                delete oldNode;
            }
        }

        /**
         * Deep copy of linked lists.
         */
        template <class Object>
        const List<Object> & List<Object>::operator=( const List<Object> & rhs )
        {
            ListItr<Object> ritr = rhs.first( );
            ListItr<Object> itr = zeroth( );

            if( this != &rhs )
            {
                makeEmpty( );
                for( ; !ritr.isPastEnd( ); ritr.advance( ), itr.advance( ) )
                    insert( ritr.retrieve( ), itr );
            }
            return *this;
        }



        #ifndef SEPARATE_CHAINING_H_
        #define SEPARATE_CHAINING_H_

        #include <vector>
        #include <cstring>


        // SeparateChaining hashh table class
        //
        // CONSTRUCTION: an initialization for ITEM_NOT_FOUND
        //               and an approximate initial size or default of 101
        //
        // ******************PUBLIC OPERATIONS*********************
        // void insert( x )       --> Insert x
        // void remove( x )       --> Remove x
        // hashhable find( x )     --> Return item that matches x
        // void makeEmpty( )      --> Remove all items
        // int hashh( string str, int tableSize )
        //                        --> Global method to hashh strings

        template <class hashhedObj>
        class hashhTable
        {
          public:
            explicit hashhTable( const hashhedObj & notFound, int size = 101 );
            hashhTable( const hashhTable & rhs )
              : ITEM_NOT_FOUND( rhs.ITEM_NOT_FOUND ), theLists( rhs.theLists ) { }

            const hashhedObj & find( const hashhedObj & x ) const;

            void makeEmpty( );
            void insert( const hashhedObj & x );
            void remove( const hashhedObj & x );

            const hashhTable & operator=( const hashhTable & rhs );
          private:
            vector<List<hashhedObj> > theLists;   // The array of Lists
            const hashhedObj ITEM_NOT_FOUND;
        };

        int hashh( const string & key, int tableSize );
        int hashh( int key, int tableSize );


        #endif

        #include <iostream>


        /**
         * Internal method to test if a positive number is prime.
         * Not an efficient algorithm.
         */
        bool isPrime( int n )
        {
            if( n == 2 || n == 3 )
                return true;

            if( n == 1 || n % 2 == 0 )
                return false;

            for( int i = 3; i * i <= n; i += 2 )
                if( n % i == 0 )
                    return false;

            return true;
        }

        /**
         * Internal method to return a prime number at least as large as n.
         * Assumes n > 0.
         */
        int nextPrime( int n )
        {
            if( n % 2 == 0 )
                n++;

            for( ; !isPrime( n ); n += 2 )
                ;

            return n;
        }

        /**
         * Construct the hashh table.
         */
        template <class hashhedObj>
        hashhTable<hashhedObj>::hashhTable( const hashhedObj & notFound, int size )
          : ITEM_NOT_FOUND( notFound ), theLists( nextPrime( size ) )
        {
        }

        /**
         * Insert item x into the hashh table. If the item is
         * already present, then do nothing.
         */
        template <class hashhedObj>
        void hashhTable<hashhedObj>::insert( const hashhedObj & x )
        {
            List<hashhedObj> & whichList = theLists[ hashh( x, theLists.size( ) ) ];
            ListItr<hashhedObj> itr = whichList.find( x );

            if( itr.isPastEnd( ) )
                whichList.insert( x, whichList.zeroth( ) );
        }

        /**
         * Remove item x from the hashh table.
         */
        template <class hashhedObj>
        void hashhTable<hashhedObj>::remove( const hashhedObj & x )
        {
           theLists[ hashh( x, theLists.size( ) ) ].remove( x );
        }

        /**
         * Find item x in the hashh table.
         * Return the matching item or ITEM_NOT_FOUND if not found
         */
        template <class hashhedObj>
        const hashhedObj & hashhTable<hashhedObj>::find( const hashhedObj & x ) const
        {
            ListItr<hashhedObj> itr;
            itr = theLists[ hashh( x, theLists.size( ) ) ].find( x );
            if( itr.isPastEnd( ) )
                return ITEM_NOT_FOUND;
            else
                return itr.retrieve( );
        }

        /**
         * Make the hashh table logically empty.
         */
        template <class hashhedObj>
        void hashhTable<hashhedObj>::makeEmpty( )
        {
            for( int i = 0; i < theLists.size( ); i++ )
                theLists[ i ].makeEmpty( );
        }

        /**
         * Deep copy.
         */
        template <class hashhedObj>
        const hashhTable<hashhedObj> &
        hashhTable<hashhedObj>::operator=( const hashhTable<hashhedObj> & rhs )
        {
            if( this != &rhs )
                theLists = rhs.theLists;
            return *this;
        }


        /**
         * A hashh routine for string objects.
         */
        int hashh( const string & key, int tableSize )
        {
            int hashhVal = 0;

            for( int i = 0; i < key.length( ); i++ )
                hashhVal = 37 * hashhVal + key[ i ];

            hashhVal %= tableSize;
            if( hashhVal < 0 )
                hashhVal += tableSize;

            return hashhVal;
        }


        /**
         * A hashh routine for ints.
         */
        int hashh( int key, int tableSize )
        {
            if( key < 0 ) key = -key;
            return key % tableSize;
        }


int N, NR;

int main()
{
    srand( time( NULL ) );

    freopen("hashhuri.in", "r", stdin);
    freopen("hashhuri.out", "w", stdout);

    int i, tip, x;

    const int ITEM_NOT_FOUND = -999999999;
    hashhTable<int> TR( ITEM_NOT_FOUND );

    scanf("%d ", &N);

    for (i = 1; i <= N; i++)
    {
        scanf("%d %d ", &tip, &x);

        if (tip == 1 && TR.find( x ) == ITEM_NOT_FOUND ) TR.insert( x );
        if (tip == 2) TR.remove(x);
        if (tip == 3) printf("%d\n", TR.find(x) != ITEM_NOT_FOUND);
    }

    return 0;
}