// Example presented by  Divakar Viswanath for CS116
// winter 2000                                                                                               

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <map>
#include <algorithm>

//return true if string word has an alphabetic character
inline bool alpha(const string word)
{
    for(int i=0; i<word.length();i++){
        char c;
        c=word[i];
        if((('a'<= c)&&(c<='z')) || ('A'<=c)&&(c<='Z'))
            return(true);
    }
    return(false);
}

//Return true if char c  a punctuation 
inline bool is_punct(char c)
{
   char punct[] = {'.', ',', ';', ':', '-', '!', '(', ')', '"','\''};
   const int num_of_punct = sizeof(punct)/sizeof(char);
   for(int i=0; i < num_of_punct; i++)
     if(c == punct[i])
       return(true);
   return false;
}

//Strip a word of leading and trailing punctuation.
inline string stripword(const string word)
{
    
    int fst=0; //the first index into word which is not a punct.
    
    while((is_punct(word[fst]))&&(fst < word.length()-1))
        fst++;


    int last=word.length()-1; //the first index from the right into
                             //word without a punct.
    while((is_punct(word[last]))&&(last>0))
        last--;
    
    if(fst > last)
        return("");
    else
        return(word.substr(fst,last-fst+1));
}



main(){
    ifstream ifile("iliad.mb.txt");
    if(ifile.fail()){
	cout<<"Couldn't open file"<<endl;
	return(0);
    }
    
    //Store the word number for every occurence of every word.
    typedef vector<int> VINT;
    map<string, VINT *> wordmap;
    int wnum = 0;
    while(!ifile.eof()){
	string curword;
	ifile>>curword;
	if(alpha(curword)){
	    wnum++;
	    string scurword = stripword(curword);
	    if(wordmap.count(scurword)>0)
		(*(wordmap[scurword])).push_back(wnum);
	    else{
		VINT *vintp = new vector<int>;//why is this needed?
		(*vintp).push_back(wnum);
		wordmap.insert(
			    map<string, VINT *>::value_type(scurword, vintp));
	    }
	}
    }
    ifile.close();
    

    //Print all the occurences of an input word
    cout<<"Name: ";
    string name;
    cin>>name;
    map<string, VINT *>::iterator it = wordmap.find(name);
    if(it!=wordmap.end()){
	VINT & ivec = *((*it).second);
	cout<<"Number of occurrences: "<<ivec.size()<<endl;
	for(int i=0; i < ivec.size(); i++){
	    if(i%8==0)
		cout<<endl;
	    cout<<ivec[i]<<"  ";
	    
	}
	cout<<endl;
    }
    
    //Print the first five things in the map
    it = wordmap.begin();
    for(int i=0; i < 5; it++, i++){
	cout<<"Entry No "<<i+1<<" is: "<<(*it).first<<
	    " with number of occurences: "<<((*it).second)->size()<<endl;
    }
}
    

   

/* Output:
Name: Helen
Number of occurrences: 39

7272  7416  9085  11183  14350  14527  14829  15089  
15241  15469  15732  15946  16203  16225  16592  17047  
17163  17361  17398  17420  17714  17906  19333  34069  
34355  34510  34682  39486  39526  39934  41437  47305  
48668  61985  63318  79147  117653  131008  152092  
Entry No 1 is: A with number of occurences: 14
Entry No 2 is: Abantes with number of occurences: 3
Entry No 3 is: Abarbarea with number of occurences: 1
Entry No 4 is: Abas with number of occurences: 1
Entry No 5 is: Abians with number of occurences: 1
*/
