// Program: Internet Ads // Author: Chuck Stewart // Purpose: main function for the solution to HW 3, CS II, Spring 2008. // // The program is organized around a vector of user objects. For // each keyword, each user is searched to generate an ad for a given // keyword. This does not scale well and we will discuss alternative // approaches in class. #include #include #include #include #include "user.h" // Add a keyword and url for an ad. If the user id is new, a new // user object must be added to the vector of users. The function // returns true if and only if the input data is correctly // formatted. This is used for error checking on the test data, but // is not strictly necessary for the assignment. bool add_keyword_and_url( std::istream & ad_ifs, std::ostream & output_ofs, std::vector & users ) { std::string keyword, user_id, url; float post_cost, click_cost; // Input the user. if ( ad_ifs >> keyword >> user_id >> url >> post_cost >> click_cost ) { // Echo the input output_ofs << '\n' << "add " << keyword << ' ' << user_id << ' ' << url << ' ' << post_cost << ' ' << click_cost << '\n'; // Search for the user id. The result of the loop that if the // user id is among the users, the found flag will be set to // true and index will store the index in the vector. unsigned int index = 0; bool found = false; for ( unsigned int i=0; i b.cost(); } // Search for a keyword among the users and the ads, generating the // required adds in their required order. bool search_keyword( std::istream & ad_ifs, std::ostream & output_ofs, std::vector & users ) { std::string keyword; // Get the input keyword and proceed if it is correct. if ( ad_ifs >> keyword ) { // Echo the input output_ofs << "\n" << "search " << keyword << '\n'; // Build a vector of urls to display. The ad_for_keyword // function returns true if an ad was generated for this keyword // and it assigns the url and post_cost values for this ad. std::string url; float post_cost; std::vector< url_display > displays; for (unsigned i=0; i!=users.size(); ++i ) if ( users[i].ad_for_keyword( keyword, url, post_cost ) ) displays.push_back( url_display(url,post_cost) ); // Output the ads. if ( displays.empty() ) output_ofs << "no ads\n"; else { output_ofs << "ads:\n"; std::sort( displays.begin(), displays.end(), greater_cost ); for ( unsigned int i=0; i & users ) { std::string keyword, url; // Check the rest of the input, checking to see if it is correct. if ( ad_ifs >> keyword >> url ) { // Echo the input output_ofs << '\n' << "click " << keyword << ' ' << url << '\n'; // Search the vector of users for the url, charging the user // found. The click function searches for the keyword / url // combination among its ads, and if it is found charges for // the click and returns true. for ( unsigned int i=0; i & users ) { // Get the keyword and ad std::string keyword, user_id; if ( ad_ifs >> keyword >> user_id ) { // Echo the input output_ofs << '\n' << "remove " << keyword << ' ' << user_id << '\n'; // Find the user and remove the ad. for ( unsigned int i=0; i & users ) { // Get the user id std::string user_id; if ( ad_ifs >> user_id ) { // Echo the input output_ofs << '\n' << "statistics " << user_id << '\n'; // Find the user id and when found generate the output. It is // crucial that output_ofs be passed by reference to the // statistics function. Passing it by value will result in // a program crash. for ( unsigned int i=0; i users; // Handle the internet ad searches one at a time, building up the // vector of users. Each input line is handled by a separate // function. If one of these returns false, the input is corrupted // and the program should quit. while ( ad_ifs >> command ) { if ( command == "add" ) { if ( !add_keyword_and_url( ad_ifs, output_ofs, users ) ) return 0; } else if ( command == "search" ) { if ( !search_keyword( ad_ifs, output_ofs, users ) ) return 0; } else if ( command == "click" ) { if ( !handle_click( ad_ifs, output_ofs, users ) ) return 0; } else if ( command == "remove" ) { remove_keyword_from_user( ad_ifs, output_ofs, users ); } else if ( command == "statistics" ) { generate_statistics_for_user( ad_ifs, output_ofs, users ); } else { std::cerr << "Invalid command: " << command << '\n'; return 0; } } return 0; }