(a)
For movie base classes, I was thinking about using an index number to represent a movie, instead of making a movie object.
But obviously thats too naive and vecy function-limited to do so. When I designing the movie base class,
and dealing with the rate of the movie, I was about to use a vector<vector<float>*> to do it, but also, it has to be limited to index accessing to a movie container, and its not flexable.
For user base classes, one user can rate more than one movie, hence there should be a collection of movies that user has rated. 
But at the same time the rating of the movie should also be stored, and the most convinience way to do it is to link the movie and rate together, in other words, make a ratedMovie object, and I thought this is a good idea and tell it to my partner, so in the movie base class we also made a ratedUser object to store the user and their rating to this movie.

comparing our final decision to our previous naive and simple ideas, this is obviously more flexible, more convinience and incresed the readability of the code. 

(b)
1) First, for reading the u.item, it is running in Theta(M), then for reading the u.data, it is running in Theta(R) to store the rating with the user&movie to corresponding values. 
2) Then it needs to run M times to calculate the average rate of each movie.
The calcAvgRate() method is running in average O(R/M) times because in average there are R/M users of one movie.
3) After that, it needs to run U times to calculate each user's ug&pug
the calcUg() is running in average O(R/U) times because in average there are R/U movies that a user rated.
the calcPug() is running in O(M) times due to the argument (vector<movie*>* movieList) 's size, and this argument is the collection of all the movies.
4) then we need to run the moviesRatedWithPug() method, which runs in O(M) times, also due to the parameter (vector<movie*>* movies)'s size.
5) after that is a sorting method required O(Mlog(M)) times computing,
and finally output the number of movies the user want to be recommended.

In this process, we have:
1) Theta(M)+Theta(R) = Theta(M+R)
2) M*O(R/M) = O(R)
3) U*(O(R/U)+O(M)) = O(R+UM)
4) O(M)
5) O(Mlog(M))

so totally this is running at:
O(2R+UM+Mlog(M))+Theta(M+R) times
