2012-04-20 134 views
3

我一直負責製作一個按標題,流派,年份,等級,主演等搜索400多部電影(鏈接在一起使用鏈接列表)的程序。搜索鏈接列表,不同的數據類型

雖然有一個問題,但我們只允許一個搜索功能來通過鏈表進行搜索。此外,該搜索功能中,我們只允許一個while循環,這是我在我的情況下,假設將是這樣的......

while (moviePtr != NULL) 

顯然他們會有很多不同的情況下,如果一個演員的搜索,或者類型搜索。在演員,流派,評級,年份,子類型和輔助角色的情況下,應該輸出找到的每一個實例。 (例如,如果Kevin Bacon在x-men和筆記本上,它不僅應該輸出其中的一個(輸出文件而不是屏幕))。

我發現自己完全被這些限制給絆倒了。 我的搜索功能將如何處理不同的數據類型? (年份和評分必須聲明爲整數)。它將如何知道我在尋找什麼?如果我正在尋找演員,我不希望它搜索標題。

任何有關如何開始和開始的建議非常感謝。

編輯: 嗨所有想到的ID更新你們什麼我做了。我有3種不同的搜索功能。一個用於數值(年份和評分),一個用於流派和演員,最後一個用於標題。

這是他們三人的代碼。 首先標題搜索。

void TitleSearched(MovieNode*head, 
       string titleSearched, 
       ofstream& outFile) 
{ 
MovieNode* moviePtr; 
bool found; 

moviePtr = head; 
found = false; 

while (moviePtr !=NULL & !found) 
{ 
    if (moviePtr-> title == titleSearched) 
    { 
     found = true; 
    } 
    else 
    { 
     moviePtr = moviePtr -> next; 
    } 

} 
if (found) 
{ 
    cout << endl << titleSearched << " has been found!\n"; 
    TitleOutput (moviePtr,outFile); 
} 
else 
{ 
    cout << endl << titleSearched << " was not found.\n"; 
} 
} 

now the year/rating search。

int NumSearched(MovieNode* head, int numSearched) 
{ 

int instances; 
MovieNode* moviePtr; 

ofstream outFile; 


    moviePtr = head; 
    instances = 0; 
    while (moviePtr !=NULL) 
    { 
     if (moviePtr-> year == numSearched) 
     { 

      instances = instances +1; 
      NumOutList(moviePtr,outFile,"year",numSearched,instances); 
      moviePtr = moviePtr -> next; 
     } 
     else if (moviePtr->rating == numSearched) 
     { 

      instances = instances +1; 
      NumOutList(moviePtr,outFile,"rating",numSearched,instances); 
      moviePtr = moviePtr -> next; 
     } 
     else 
     { 
      moviePtr = moviePtr ->next; 
     } 


    } 
return instances; 
} 

最後流派/演員搜索。

int ItemSearch (MovieNode* head,string itemSearched, ofstream& outFile) 
{ 
int instances; 
MovieNode* moviePtr; 


moviePtr = head; 
instances = 0; 






    while (moviePtr !=NULL) 
    { 
     if (moviePtr-> genre == itemSearched || moviePtr ->subGenre == itemSearched) 
     { 

      instances = instances +1; 
      OutList(moviePtr,outFile,"Genre",itemSearched,instances); 
      moviePtr = moviePtr -> next; 
     } 
     else if (moviePtr->leadActor == itemSearched || moviePtr->supportActor == itemSearched) 
     { 

      instances = instances +1; 
      OutList(moviePtr,outFile,"Actor",itemSearched,instances); 
      moviePtr = moviePtr -> next; 
     } 
     else 
     { 
      moviePtr = moviePtr ->next; 
     } 


    } 



    return instances; 
} 

我想提醒你們,我的任務是什麼。 1.結合這三個搜索功能爲一體 2.具有隻有一個while循環搜索 3.在任何給定的功能只有一個返回(但是,ID假設這將是一個void函數結合時)

我主要問題我貝雷夫是我的整理和絃樂。我不能將評級或年份聲明爲字符串。只是在整體梳理所有三個代碼的格式是給我一個頭痛

+0

您的搜索條件是否指定您要查找的內容「凱文培根」+「演員」還是你應該猜猜他們在找什麼? – Kiril 2012-04-20 19:49:18

+0

用戶使用枚舉類型從菜單中選擇想要搜索的內容,例如,類型爲0,退出,1-標題搜索,2-搜索我的評分,3-按年搜索,4-按演員搜索, etc – 2012-04-20 20:21:13

+0

增加了一個新的編輯。多謝你們! – 2012-04-23 01:45:43

回答

2

你可以用接受謂詞作爲參數的方式編寫你的搜索功能。謂詞是某種「函數類型」(意思是說,任何有能力被稱爲「函數」的東西 - 它可以是函數,lambda或函數對象..)

在C++標準庫

,謂詞用於許多的標準算法,所以它是常見的,你會看到代碼(使用標準集裝箱)是這樣的:

#include <iostream> 
#include <string> 
#include <vector> 
#include <algorithm> 
#include <cctype> 

bool begins_with_s(std::string s) 
{ 
    return s.length() > 0     && 
      std::toupper(s.at(0)) == 'S'; 
} 

bool contains_a_number(std::string s) 
{ 
    return std::find_if(s.begin(), s.end(), std::isdigit) != s.end(); 
} 

int main() 
{ 
    std::string movies_array[] = 
    { 
     "King Kong", 
     "Singin in the Rain", 
     "Die Hard 2", 
     "Superman", 
     "Star Wars", 
     "Jaws 3" 
    }; 
    std::vector<std::string> movies(std::begin(movies_array), 
            std::end(movies_array)); 

    // Use predicate - count if the movie name begins with "S" 
    std::cout << "Movies beginning with S: " 
     << std::count_if(movies.begin(), movies.end(), begins_with_s) 
     << std::endl; 

    // Use predicate - count if the movie name contains a number 
    std::cout << "Movies containing a number: " 
     << std::count_if(movies.begin(), movies.end(), contains_a_number) 
     << std::endl; 
} 

的方式,C++標準算法以這種方式實現的步驟是接受模板參數代表謂語,沿

template< typename PredicateType > 
void my_function(PredicateType predicate) 
{ 
    Movie my_movie; 
    predicate(my_movie); 
} 

行這是從思維的函數式編程學校的技術 - 傳遞一個函數的功能(處理功能作爲「第一次ss公民「)。

2

您可以讓您的搜索功能將「匹配」功能作爲其參數,並在每部電影上調用此匹配功能以查看電影是否匹配。然後您可以使用不同的匹配功能調用您的搜索功能。

事情是這樣的:

template <typename MatchFunction> 
void search_movies(movie* moviePtr, MatchFunction match) 
{ 
    while (moviePtr != NULL) 
    { 
     if (match(*moviePtr)) 
     { 
      // output movie 
     } 
     moviePtr = moviePtr->next; 
    } 
} 

然後,您可以聲明匹配的功能是這樣的:

bool matches_actor(movie& m, const std::string& actor) 
{ 
    return m.actor == actor; 
} 

,並用這樣的特定查詢調用它:

search_movies(moviePtr, std::bind(matches_actor, _1, "Morgan Freeman")); 

std::bind是來自<functional>的C++ 11函數;您可以等效使用boost::bindstd::bind2nd

或者,如果你喜歡做的事情更加C風格的方式,你可以做這樣的事情:

void search_movies(movie* moviePtr, bool (*match)(movie*, void*), void* match_arg) 
{ 
    while (moviePtr != NULL) 
    { 
     if (match(moviePtr, match_arg)) 
     { 
      // output movie 
     } 
     moviePtr = moviePtr->next; 
    } 
} 
... 
bool matches_actor(movie* m, void* actor) 
{ 
    return m.actor == *((std::string*)actor); 
} 
... 
std::string actor = "Morgan Freeman"; 
search_movies(moviePtr, &matches_actor, (void*)(&actor)); 
+0

對不起,我忘了提及我們只允許在我們所有的功能,包括這一個返回。 – 2012-04-20 20:23:00

+0

@RileyFrancona:你在哪裏看到多個回報? – HighCommander4 2012-04-20 20:25:11

2

除了傳遞仿函數的選項來檢查的比賽中,有是其他選項。一個這樣的選擇將採取一系列可選條件檢查(可以使用boost::optional或手工方法,或者使用指針,例如:

void print_matching(node* list, int * year, std::string * actor...) { 
    // iterate over the list: 
    while (...) { 
     if ( (!year || ptr->year == *year) 
     && (!actor || ptr->actor == *actor) 
     && ... 
     ) 
     { 
      // Film matches, print it 
     } 
    } 
} 

爲了簡化函數簽名,你可以創建一個search_pattern型封裝你要測試的字段(使用不同的方法例如:布爾變量來確定期權):

struct pattern { 
    bool check_actor; 
    std::string actor; 
    bool check_year; 
    int year; 
}; 

void print_matching(node* list, pattern const & p) { 
    // iterate over the list: 
    while (...) { 
     if ( (!p.check_year || ptr->year == p.year) 
     && (!p.check_actor || ptr->actor == p.actor) 
     && ... 
     ) 
     { 
      // Film matches, print it 
     } 
    } 
} 

在最後這種情況下,你可以測試實際移動到pattern對象,並有一個函數:

bool pattern :: matches(movie cosnt & m)const { return(!check_year || m.year == year) & &(!check_actor || m.actor == actor); } 空隙print_matching(節點*列表中,圖案常量& P){// 遍歷列表: 而(...){ 如果(p.matches(列表 - >數據)) { //電影匹配,打印 } } }

+0

大家好,我以爲身份證更新了你我所做的決定。我把搜索功能分成三個不同的功能,一個用於標題,一個用於年份和評分,另一個用於流派和演員。下面是他們每個人的代碼。 – 2012-04-23 01:38:36