#include <iostream.h>
#include <string.h>

class AArray {

	// maintains a set S of strings and a function f(s) -> integer

public:

	// if (s not \in S) add s to S
	// return reference to f(s)
	int & operator [] (const char *s);    

	// if (s \in S) return 0; else return 1;
	int present (const char *s);

	AArray(const int n=10);  // can set the initial allocation
	virtual ~AArray();

private:

	// simple implementation using a dynamically sized array
	// we assume max size of string
	const int _max_size  = 32;

	// single element in array
	struct Elem {
		char _str[_max_size+1];
		int  _v;
	};

	// statically allocated array
	Elem *_elem;

	// number of used elements in array
	int  _count;

	// number of allocated elements in array
	int  _max_count;

	// internal find, returns the position of s in the array, -1 if s not in S
	int find(const char *s);

        // print out everything
        friend ostream & operator <<
                ( ostream & Out, const AArray & Value );

};

// start off with 0 count
AArray::AArray(const int n) {
	_count = 0;
	_max_count = n;
	_elem = new Elem[_max_count];
}

// nothing to do
AArray::~AArray() {
	delete [] _elem;
}


// search through array for s
int AArray::find(const char*s) {
	for(int i=0;i<_count;i++) if(strcmp(s,_elem[i]._str)==0) return i;
	return -1;
}	

// if we can find it, it's there
int AArray::present(const char*s) {
	return (find(s)<0)?0:1;
}

// get reference to f(s)
int & AArray::operator [] (const char *s) {

	// find s
	int i=find(s);

	if(i<0) {
		// if s is not in S, add it
                if( _count >= _max_count ) 
		{ 
			// if we overflow array, add more space

			int new_max_count = _max_count * 2;       // double space
			Elem *new_elem = new Elem[new_max_count]; // allocate new array

			// copy over to new_elem
			for (int j=0;j<_max_count;j++) new_elem[j] = _elem[j];
		
			// delete old
			delete [] _elem;
	
			_elem = new_elem;
			_max_count = new_max_count;
		}
		i = _count;
		_count++;
		strncpy(_elem[i]._str,s,_max_size);
		_elem[i]._v = 0;
	}
	return _elem[i]._v;
}

// print it out
ostream & operator << ( ostream & Out, const AArray & Value ) {
        for(int i=0;i<Value._count;i++) Out << Value._elem[i]._str << " " << Value._elem[i]._v << endl;
        return Out;
}

// trivial use example
int main()
{
        AArray a(1);

        a["hello"]++;
        cout 	<< a["hello"]++
        	<< " "
        	<< a["goodbye"]++
        	<< " "
        	<< a["hello"]
        	<< " "
        	<< a["goodbye"]
        	<< "\n";

	cout	<< a;

        return 0;
}
