CS107 Assignment 2: Six Degrees of Kevin Bacon
任务地址:https://see.stanford.edu/materials/icsppcs107/09-Assignment-2-Six-Degrees.pdf
Task I: The imdb class
补全 imdb.cc
基本就是给你一个长数据的头指针 如下,然后要你把里面的各种信息提取出来,期间还用到了二分法查找,用的最多的还是指针的强制类型转换。 const type* p 多使用,表示指针指向的内容不可改变,因为我们不打算改数据。
可以看到用了很多 \0 填充,这是为了保证每个小块4字节,因为编译器需要编译时需要确保 int 数据是4字节对齐的,不然就会出现bus error.
代码:
string getName(const void * p)
{
string name;
while( *((char*)p) != '\0')
{
name += *((char*)p);
p = (char*)p +1;
}
return name;
}
//2分法得到要找演员的offset
int imdb::getOffest(int begin, int end, const string name) const
{
int mid = begin + (end -begin)/2;
if(begin > end) return -1;
else
{
string midname = getName( (char*)actorFile + *( (int*)actorFile+mid ) );
if (midname == name)
return *((int*)actorFile + mid);
else if(midname > name)
return getOffest(begin, mid -1, name);
else return getOffest(mid+1, end, name);
}
}
int getYear(const void *p)
{
while (*((char*)p) != '\0')
p = (char*)p +1;
p = (char*)p +1;
return int(*(char*)p) + 1900;
}
//2分法得到要找电影的offset
int imdb::getOffestm(int begin, int end, film movie) const
{
int mid = begin + (end -begin)/2;
if(begin > end) return -1;
else
{
string midname = getName( (char*)movieFile + *( (int*)movieFile+mid ) );
int year = getYear((char*)movieFile + *( (int*)movieFile+mid ));
film temp;
temp.title = midname;
temp.year = year;
//这样子我们就可以用film自定义的操作符 == 和 < 了
if (temp == movie)
return *((int*)movieFile + mid);
else if(movie < temp)
return getOffestm(begin, mid -1, movie);
else return getOffestm(mid+1, end, movie);
}
}
bool imdb::getCredits(const string& player, vector<film>& films) const
{
int begin = 1;
int end = *((int*)actorFile);
int offset = getOffest(begin, end, player);
const char* actordata = (char*)actorFile + offset; //找到的演员的数据开头指针
while( *actordata != '\0')
actordata= actordata +1;
while( *actordata == '\0')
actordata= actordata +1;
int num = *(short*)actordata;
actordata= actordata +2;
while( *actordata == '\0')
actordata= actordata +1;//指针指到了演员数据中的电影索引部分,电影个数为num
while (num > 0)
{
int movieoffest = *(int*)actordata;
film temp;
temp.title = getName((char*)movieFile + movieoffest);
temp.year = getYear((char*)movieFile + movieoffest);
films.push_back(temp);
actordata= actordata +4;
num--;
}
if (films.size() > 0)
return true;
else
return false;
}
bool imdb::getCast(const film& movie, vector<string>& players) const
{
int begin = 1;
int end = *((int*)movieFile);
int offset = getOffestm(begin, end, movie);
const char* moviedata = (char*)movieFile + offset; //找到的电影的数据开头指针
while( *moviedata != '\0')
moviedata= moviedata +1;
moviedata= moviedata + 2;
while( *moviedata == '\0')
moviedata= moviedata +1;
int num = *(short*)moviedata;
moviedata= moviedata +2;
if( *moviedata == '\0' && *(moviedata+1) == '\0') //服了,找了半天找不到bug,原来还有一个条件,后面可能存在两个\0
moviedata= moviedata +2;//指针指到了电影数据中的演员索引部分,演员个数为num
while (num > 0)
{
int actoroffest = *(int*)moviedata;
string name;
name = getName((char*)actorFile + actoroffest);
players.push_back(name);
moviedata = moviedata +4;
num--;
}
if (players.empty())
return false;
else
return true;
}
结果展示:
Please enter the name of an actor or actress (or [enter] to quit): Jack Nicholson
Jack Nicholson has starred in 71 films.
These films are:
1.) About Schmidt (2002)
2.) AFI Life Achievement Award: A Tribute to Barbra Streisand (2001)
3.) America at the Movies (1976)
4.) Anger Management (2003)
5.) As Good as It Gets (1997)
6.) Back Door to Hell (1964)
7.) Batman (1989)
8.) Blood and Wine (1996)
9.) Border, The (1982)
10.) Broadcast News (1987)
.... skipping one or more records...
62.) Terms of Endearment (1983)
63.) Terror in the Aisles (1984)
64.) Terror, The (1963)
65.) Tommy (1975)
66.) Too Soon to Love (1960)
67.) Two Jakes, The (1990)
68.) Who's Tommy, the Amazing Journey, The (1993)
69.) Wild Ride, The (1960)
70.) Witches of Eastwick, The (1987)
71.) Wolf (1994)
[Press enter to continue]
Jack Nicholson has worked with 2497 other people.
Those other people are:
1.) 'Snub' Pollard
2.) Aaron Eckhart
3.) Aaron Fiore
4.) Aaron Saxon
5.) Aaron Sorkin
6.) Abdallah Mtulu
7.) Abdul Rezkiv
8.) Abraham Mishkind
9.) Abraham Sofaer
10.) Adalberto Cortez
.... skipping one or more records...
2488.) Wyn Costello
2489.) Xander Berkeley
2490.) Ya Parulava
2491.) Yakov Smirnoff
2492.) Yaphet Kotto
2493.) Yeardley Smith
2494.) Yves Montand
2495.) Zachary Pauliks
2496.) Zack Abramowitz
2497.) Zsa Zsa Gabor
[Press enter to continue]
Task II: Implementing Search
找最短路径,因为路径没有cost, 所以说白了就是遍历,任务给出了广度优先搜索的算法,依葫芦画瓢就是
(广搜用队列,深搜用栈)
Here’s the general algorithm I used for my own generateShortestPath functio
list<path> partialPaths; // functions as a queue
set<string> previouslySeenActors;
set<film> previouslySeenFilms;
create a partial path around the start actor;
add this partial path to the queue of partial paths;
while queue isn’t empty and its front element is of length 5 or less
pull off front path (involves both front and pop_front)
look up last actor’s movies
for each movie in his/her list of movies you’ve not seen before
add movie to the set of previously seen movies
look up movie’s cast
for each cast member you’ve not seen before
add cast member to set of those previously seen
clone the partial path
add the movie/costar connection to the clone
if you notice the costar is your target, then print the path and return
otherwise add this new partial path to the end of the queue
if the while loop ends, print that you didn’t find a path
代码:
path shortpath(source);
list<path> partialPaths;
set<string> previouslySeenActors;
set<film> previouslySeenFilms;
partialPaths.push_back(shortpath);
while ( !partialPaths.empty() && (partialPaths.front().getLength() <= 5) )
{
path path1=partialPaths.front();
partialPaths.pop_front();
string actor = path1.getLastPlayer();
vector<film> films;
bool a=db.getCredits(actor,films);
for (auto iter = films.cbegin(); iter != films.cend(); iter++)
{
if(previouslySeenFilms.count(*iter) != 0 )
continue;
else
previouslySeenFilms.insert(*iter);
vector<string> actors;
bool b = db.getCast(*iter, actors);
for(auto iter2 = actors.cbegin(); iter2 != actors.cend(); iter2++)
{
if(previouslySeenActors.count(*iter2) != 0 )
continue;
else
previouslySeenActors.insert(*iter2);
path temp = path1;
temp.addConnection(*iter, *iter2);
if(*iter2 == target)
{
cout<<temp<<endl;
return 0;
}
else
partialPaths.push_back(temp);
}
}
}
结果:
Actor or actress [or <enter> to quit]: Jerry Cain
Another actor or actress [or <enter> to quit]: Kevin Bacon
Jerry Cain was in "No Rules" (2005) with Dian Bachar.
Dian Bachar was in "Adventures of Rocky & Bullwinkle, The" (2000) with Robert De Niro.
Robert De Niro was in "Sleepers" (1996) with Kevin Bacon.