///////////////////////// /////////headers///////// ///////////////////////// #include #include #include #include using namespace std; #include //#include //#include //#include ///////////////////////// //////////const////////// ///////////////////////// #define STR_MAX 128 #define PRM_MAX 4 #define PFX_MAX 2 ///////////////////////// ///////help const//////// ///////////////////////// const char h_Start[128] = "\n\t\t\t\t\t\tGeGorg's Ludosoft International\n\n A l b e r t o T e x t C o m p o s e r 2 0 1 0 ed\n\n"; const char h_Stop[128] = "\n\t\t\t\t\t\tProgram terminated. See you soon!\n\n\tAlby\n\n"; const char h_cmd[7][16] = {"exit","help","read","clear","speak","seed","stats"}; const char h_syn[7][16] = {""," [topic]"," ",""," [firstword]"," [num]",""}; const char h_help[7][128] = {"Terminate the program and closes all files", "Shows the help index, or some informations about command \"topic\" if specified", "Adds to the dictionary words and syntax from \"filepath\"", "Wipes out the actually stored dictionary", "Makes Alberto speak randomly with the stored dictionary, starting by \"firstword\" (defaults to \".\").", "Show seed value, or initialize random number generator with \"num\"", "Displays several statistic informations"}; const int h_ncmd = 7; ///////////////////////// ///////local types/////// ///////////////////////// template class count_map : public pair< int, map< string, count_map > > { public: void put( string W[] ) { this->first++; this->second[W[0]].put( W+1 ); } string get( string W[], int np = N ) const { typename map< string, count_map >::const_iterator span; int r = (int)( rand() / ( RAND_MAX + 1.0 ) * this->first ); if ( np == 0 ) for ( span = this->second.begin(); span != this->second.end(); ++span ) { r -= span->second.first; if ( r < 0 ) return span->first; } else return this->second.find(W[0])->second.get( W+1, np-1 ); } bool verify() const { typename map< string, count_map >::const_iterator span; int acc = 0; if ( this->first == 0 ) return this->second.empty(); if ( this->first < 0 || this->second.empty() ) return false; for ( span = this->second.begin(); span != this->second.end(); ++span ) { acc += span->second.first; if ( !span->second.verify() ) return false; } return (acc == this->first); } void stats( int C[], long long Q[] ) const { typename map< string, count_map >::const_iterator span; C[N+1]++; Q[N+1]+=(long long)this->first * this->first; for ( span = this->second.begin(); span != this->second.end(); ++span ) span->second.stats( C, Q ); } }; template<> class count_map<-1> { public: int first; count_map() { first = 0; } void put( string W[] ) { this->first++; } string get( string W[], int np = 0 ) const // Questo metodo non dovrebbe mai essere richiamato { return ""; } bool verify() const { return ( this->first >= 0 ); } void stats( int C[], long long Q[] ) const { C[0]++; Q[0]+= (long long)this->first * this->first; } }; ///////////////////////// ///////global var//////// ///////////////////////// count_map<> *pfx_map; int Seed = 0; ///////////////////////// ////inline functions///// ///////////////////////// char DownCase( char Ch ) { if ( Ch >= 'A' && Ch <= 'Z' ) return Ch + 'a' - 'A'; return Ch; } void StrDownCase( char *Str ) { int i = strlen( Str ); for (i--;i>=0;i--) Str[i] = DownCase( Str[i] ); } void ReadParameters( char *Str, char *Par ) { int i, j, k, Dim; i = j = k = 0; Dim = strlen( Str ); while ( Str[i] == ' ' && i < Dim ) i++; while ( i < Dim ) { if ( Str[i] == ' ' && Str[i-1] != ' ' && k < PRM_MAX ) { Par[j + k*STR_MAX] = 0; j=0; k++; } else if ( Str[i] != ' ' ) { Par[j + k*STR_MAX] = Str[i]; j++; } i++; } Par[j + k*STR_MAX] = 0; Par[(k+1)*STR_MAX] = 0; } ///////////////////////// /////main functions////// ///////////////////////// ///////////////////////// ////////interface//////// ///////////////////////// int Cmd_Read( char Param[][STR_MAX] ) { if ( Param[1][0] == 0 ) { printf( "\n Too few parameters." ); return 0; } if ( Param[2][0] != 0 ) { printf( "\n Too much parameters." ); return 0; } ifstream Fin( Param[1] ); string Word[2*PFX_MAX+2]; string first[PFX_MAX]; int i; if ( Fin.fail() ) { printf( "\n Could not open file \"%s\".", Param[1] ); return 1; } for ( i=0; i> Word[i+1]; if ( Fin.fail() ) { printf( "\n I/O error." ); return 1; } first[i] = Word[i+1]; } i=0; while ( !Fin.eof() ) { Fin >> Word[i]; if ( Fin.fail() && Fin.eof() ) break; if ( Fin.fail() || Word[i].empty() ) { printf( "\n I/O error. Vocabulary might be corrupted." ); return 1; } Word[i+PFX_MAX+1] = Word[i]; pfx_map->put( Word + i + 1 ); i = (i+1)%(PFX_MAX+1); } for ( int j=0; jput( Word + i + 1 ); i = (i+1)%(PFX_MAX+1); } Fin.close(); if ( !pfx_map->verify() ) { printf( "\n Unexpected error. Vocabulary might be corrupted." ); return 1; } printf( "\n Reading file \"%s\" succeded.", Param[1] ); return 1; } int Cmd_Clear( char Param[][STR_MAX] ) { int i, j; if ( Param[1][0] != 0 ) { printf( "\n Too much parameters." ); return 0; } delete pfx_map; pfx_map = new count_map<>; printf( "\n The Vocabulary has been cleared." ); return 1; } int Cmd_Speak( char Param[][STR_MAX] ) { string Word[2*PFX_MAX]; int i; if ( Param[2][0] != 0 && Param[1][0] != 0 ) { printf( "\n Too much parameters." ); return 0; } if ( pfx_map->first == 0 ) { printf( "\n No dictionay stored. Use first \"read \"." ); return 1; } if ( !pfx_map->verify() ) { printf( "\n Corrupted dictionary." ); return 1; } if ( Param[1][0] == 0 ) { if ( pfx_map->second.count( "." ) == 0 ) Word[0] = pfx_map->get( Word, 0 ); else Word[0] = "."; } else { if ( pfx_map->second.count( Param[1] ) == 0 ) { printf( "\n No matches for \"%s\" in dictionary.", Param[1] ); return 1; } Word[0] = Param[1]; } Word[PFX_MAX] = Word[0]; if ( Word[0] != "." ) cout << " " << Word[0]; for ( i=1; iget( Word, i ); Word[i+PFX_MAX] = Word[i]; cout << " " << Word[i]; } for ( i=0; ; ) { Word[i] = pfx_map->get( Word + i, PFX_MAX ); Word[i+PFX_MAX] = Word[i]; cout << " " << Word[i]; i = (i+1)%PFX_MAX; if ( i==0 ) { cout.flush(); char c = getchar(); if ( c == '\n' ) break; } } } int Cmd_Seed( char Param[][STR_MAX] ) { if ( Param[1][0] != 0 && Param[2][0] != 0 ) { printf( "\n Too much parameters." ); return 0; } if ( Param[1][0] == 0 ) { printf( "\n Seed : %d.", Seed ); return 1; } if ( sscanf( Param[1], "%d", &Seed ) != 1 ) { printf( "\n Invalid argument \"%s\": \"num\" must be an integer.", Param[1] ); return 0; } srand( Seed ); printf( "\n Seed set to %d.", Seed ); return 1; } int Cmd_Stats( char Param[][STR_MAX] ) { int Count[PFX_MAX+2]; long long Quad[PFX_MAX+2]; double f; if ( Param[1][0] != 0 ) { printf( "\n Too much parameters." ); return 0; } for ( int i=PFX_MAX+1; i>=0; i-- ) Count[i] = Quad[i] = 0; pfx_map->stats( Count, Quad ); printf( "\n Total map size: %d\n\nPrefix\tCount\tAvg\tStd Dev\n", pfx_map->first ); for ( int i=PFX_MAX; i>=0; i--) { f = pfx_map->first; f *= f; f /= Count[i]; f = Quad[i] - f; f /= Count[i]; printf( "%d\t%d\t%.2f\t%.2f\n", i, Count[i], (double)pfx_map->first / Count[i], sqrt(f) ); } } int exec( int cmd, char Par[][STR_MAX] ) { if ( cmd == 2 ) return Cmd_Read( Par ); if ( cmd == 3 ) return Cmd_Clear( Par ); if ( cmd == 4 ) return Cmd_Speak( Par ); if ( cmd == 5 ) return Cmd_Seed( Par ); if ( cmd == 6 ) return Cmd_Stats( Par ); return 0; } int execHelp( char Par[][STR_MAX] ) { int i; if ( Par[1][0] != 0 && Par[2][0] != 0 ) { printf( "\n Too much parameters." ); return 0; } if ( Par[1][0] == 0 ) { printf( "\n Help synopsis: %s%s\n", h_cmd[1], h_syn[1] ); printf( "\n Avalaible topics:\n" ); for ( i=0; i " ); fgets( Input, STR_MAX, stdin ); if ( Input[strlen(Input)-1] == '\n' ) Input[strlen(Input)-1] = 0; else { fgets( Input, STR_MAX, stdin ); while ( Input[strlen(Input)-1] != '\n' ) fgets( Input, STR_MAX, stdin ); printf( "\n Input buffer overflow. Try \"%s\".", h_cmd[1] ); Input[0] = 0; } ReadParameters( Input, Param[0] ); if ( strlen( Param[0] ) ) { StrDownCase( Param[0] ); if ( strcmp( Param[0], h_cmd[0] ) == 0 ) { if ( Param[1][0] == 0 ) return 0; printf( "\n Too much parameters. Synopsis: %s%s", h_cmd[i], h_syn[i] ); return 1; } if ( strcmp( Param[0], h_cmd[1] ) == 0 ) { if ( execHelp( Param ) == 0 ) printf( " Synopsis: %s%s", h_cmd[1], h_syn[1] ); return 1; } for (i=2; i; srand(Seed); printf( "%s", h_Start ); while ( MainLoop( Input, Param ) ); printf( "%s", h_Stop ); return 0; }