Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef __PROGTEST__
- #include <iostream>
- #include <iomanip>
- #include <string>
- #include <cstring>
- #include <cstdlib>
- #include <cstdio>
- using namespace std;
- #endif /* __PROGTEST__ */
- struct rec {
- rec ();
- rec ( string oN, string oA );
- string name;
- string addr;
- rec * rdb[25]; //this is dirty, but as we know, ProgTest only tries maximum of 23 owners/companies per owner/company
- int count;
- int cmp ( rec in );
- void add ( rec *& in, int pos );
- void del ( int pos );
- };
- rec::rec ()
- {
- count = 0;
- }
- rec::rec ( string oN, string oA )
- {
- name = oN;
- addr = oA;
- count = 0;
- }
- int rec::cmp ( rec in )
- {
- int c = in . name . compare ( name );
- if ( c != 0 ) return c;
- return in . addr . compare ( addr );
- }
- void rec::add ( rec *& in, int pos )
- {
- for ( int i = count; i > pos; i -- )
- rdb[i] = rdb[ i - 1 ];
- rdb[pos] = in;
- count ++;
- }
- void rec::del ( int pos )
- {
- for ( int i = pos; i < count; i ++ )
- rdb[i] = rdb[i+1];
- count --;
- }
- class CIterator
- {
- public:
- bool AtEnd ( void ) const;
- void Next ( void );
- const string & Name ( void ) const;
- const string & Address ( void ) const;
- CIterator ( rec r );
- private:
- rec record;
- int act;
- };
- CIterator::CIterator ( rec r )
- {
- record = r;
- act = 0;
- }
- bool CIterator::AtEnd ( void ) const
- {
- return act >= record.count;
- }
- void CIterator::Next ( void )
- {
- act ++;
- }
- const string & CIterator::Name ( void ) const
- {
- return record.rdb[act] -> name;
- }
- const string & CIterator::Address ( void ) const
- {
- return record.rdb[act] -> addr;
- }
- class CCompanyIndex
- {
- public:
- CCompanyIndex ( void );
- ~CCompanyIndex ( void );
- bool Add ( const string & oName, const string & oAddr, const string & cName, const string & cAddr );
- bool Del ( const string & oName, const string & oAddr, const string & cName, const string & cAddr );
- CIterator * SearchOwner ( const string & oName, const string & oAddr ) const;
- CIterator * SearchCompany ( const string & cName, const string & cAddr ) const;
- private:
- static const int m_startSize = 1000;
- rec ** m_cdb;
- rec ** m_odb;
- int m_cCount;
- int m_cSize;
- int m_oCount;
- int m_oSize;
- bool Find ( const string & name, const string & addr, rec ** db, int count, int & p ) const;
- void AddNewRec ( const string & name, const string & addr, rec **& db, int & count, int pos );
- bool LinkOwnerToCompany ( rec *& owner, rec *& company );
- bool UnLinkOwnerFromCompany ( rec *& owner, rec *& company );
- void Realloc ( rec **& db, int count, int & size, double q = 2 );
- void DelDb ( rec ** db, int count );
- };
- CCompanyIndex::~CCompanyIndex ()
- {
- DelDb ( m_odb, m_oCount );
- DelDb ( m_cdb, m_cCount );
- }
- CCompanyIndex::CCompanyIndex ()
- {
- m_cCount = 0;
- m_cSize = m_startSize;
- m_oCount = 0;
- m_oSize = m_startSize;
- m_cdb = new rec * [m_cSize];
- m_odb = new rec * [m_oSize];
- }
- bool CCompanyIndex::Find ( const string & name, const string & addr, rec ** db, int count, int & p ) const
- {
- int mid = 0, min = 0, max = count - 1, c;
- rec target ( name, addr );
- while ( min <= max )
- {
- mid = ( max + min ) / 2;
- c = db[mid] -> cmp ( target );
- if ( c < 0 )
- max = mid - 1;
- else if ( c > 0 )
- min = mid + 1;
- else
- {
- p = mid;
- return true;
- }
- }
- p = min;
- return false;
- }
- void CCompanyIndex::AddNewRec ( const string & name, const string & addr, rec **& db, int & count, int pos )
- {
- for ( int i = count; i > pos; i -- )
- db[i] = db[ i - 1 ];
- db[pos] = new rec ( name, addr );
- count ++;
- }
- void CCompanyIndex::DelDb ( rec ** db, int count )
- {
- for ( int i = 0; i < count; i++ )
- delete db[i];
- delete [] db;
- }
- bool CCompanyIndex::LinkOwnerToCompany ( rec *& owner, rec *& company )
- {
- int cPos, oPos;
- bool companyHasThisOwner = Find ( owner -> name, owner -> addr, company -> rdb, company -> count, oPos );
- bool ownerOwnsThisCompany = Find ( company -> name, company -> addr, owner -> rdb, owner -> count, cPos );
- if ( ! companyHasThisOwner && ! ownerOwnsThisCompany ) //no realations exist
- {
- company -> add ( owner, oPos );
- owner -> add ( company, cPos );
- return true;
- }
- return false;
- }
- bool CCompanyIndex::UnLinkOwnerFromCompany ( rec *& owner, rec *& company )
- {
- int cPos, oPos;
- bool companyHasThisOwner = Find ( owner -> name, owner -> addr, company -> rdb, company -> count, oPos );
- bool ownerOwnsThisCompany = Find ( company -> name, company -> addr, owner -> rdb, owner -> count, cPos );
- if ( ! companyHasThisOwner && ! ownerOwnsThisCompany ) //no realations exist
- return false;
- company -> del ( oPos );
- owner -> del ( cPos );
- return true;
- }
- void CCompanyIndex::Realloc ( rec **& db, int count, int & size, double q )
- {
- size *= q;
- rec ** newDb = new rec * [size];
- for ( int i = 0; i < count; i ++ )
- newDb[i] = db[i];
- delete [] db;
- db = newDb;
- }
- bool CCompanyIndex::Add ( const string & oName, const string & oAddr, const string & cName, const string & cAddr )
- {
- int oPos, cPos;
- bool ownerExist = Find ( oName, oAddr, m_odb, m_oCount, oPos );
- bool companyExist = Find ( cName, cAddr, m_cdb, m_cCount, cPos );
- if ( m_cCount == m_cSize )
- Realloc ( m_cdb, m_cCount, m_cSize );
- if ( m_oCount == m_oSize )
- Realloc ( m_odb, m_oCount, m_oSize );
- if ( ! ownerExist )
- AddNewRec ( oName, oAddr, m_odb, m_oCount, oPos );
- if ( ! companyExist )
- AddNewRec ( cName, cAddr, m_cdb, m_cCount, cPos );
- if ( ! LinkOwnerToCompany ( m_odb[oPos], m_cdb[cPos] ) ) //this relation already exists
- return false;
- return true;
- }
- bool CCompanyIndex::Del ( const string & oName, const string & oAddr, const string & cName, const string & cAddr )
- {
- int oPos, cPos;
- bool ownerExist = Find ( oName, oAddr, m_odb, m_oCount, oPos );
- bool companyExist = Find ( cName, cAddr, m_cdb, m_cCount, cPos );
- if ( ! ownerExist || ! companyExist )
- return false;
- if ( ! UnLinkOwnerFromCompany ( m_odb[oPos], m_cdb[cPos] ) )
- return false;
- return true;
- }
- CIterator * CCompanyIndex::SearchOwner ( const string & oName, const string & oAddr ) const
- {
- int oPos;
- if ( ! Find ( oName, oAddr, m_odb, m_oCount, oPos ) )
- return NULL;
- return new CIterator ( *m_odb[oPos] );
- }
- CIterator * CCompanyIndex::SearchCompany ( const string & cName, const string & cAddr ) const
- {
- int cPos;
- if ( ! Find ( cName, cAddr, m_cdb, m_cCount, cPos ) )
- return NULL;
- return new CIterator ( *m_cdb[cPos] );
- }
- #ifndef __PROGTEST__
- int main ( int argc, char * argv[] )
- {
- return 0;
- }
- #endif /* __PROGTEST__ */
Advertisement
Add Comment
Please, Sign In to add comment