2013-04-10 68 views
2

我對C++很新,我正在使用HashTables創建一個程序。這是作業。這是我第一次使用和創建HashTables,所以請提前原諒我,我完全不知道我在做什麼。我現在面臨的主要問題是將我的remove()函數合併。我可以得到代碼進行編譯,但是當我運行測試程序時,它崩潰了。該錯誤,我收到是HashTable刪除函數C++

列表迭代器不decrementable

我立足我刪除功能關閉我的教授,爲我們提供了插入功能的。只是改變了一些東西。這是我的班級HTable和我的remove()功能。

class HTable 
{ 
public: 
    HTable(int size); 
    void insert( const string &s); 
    void remove(string key); 

private: 
    vector<list<string>> List; 
    int currSize; 
    int tableSize; 
    int hash(const string &key); 
    int hashFunction(string key); 
    int HTableSize; 
    int *status_arr; 
    ostream & operator <<(ostream &); 
}; 

remove()功能

inline void HTable::remove(string key) 
{ 
    list<string> List; 

    if(find(List.begin(), List.end(), key) == List.begin()) 
    { 
     List.pop_back(); 
    } 
} 
+0

總是刪除最終項目似乎是一個壞主意。 – 2013-04-11 01:34:35

+0

由於您已經在使用'STL',只需使用'std :: remove_if()'而不是'std :: find()'。 – Chad 2013-04-11 01:44:47

+0

此外,您的'列表列表;'對象是'remove()'函數的本地 - 是隻是複製/粘貼到您的問題的錯誤?那個對象顯然沒有內容。 – Chad 2013-04-11 01:47:59

回答

0
inline void HTable::remove(string key) 
{ 
    list<string> List; 

    if(find(List.end(), List.begin(), key) == List.begin()) 
    {   //^^^^^^^^^^^^^^^^^^^^^^^^^ 
    List.pop_back(); 
    } 

} 

你應該把List.begin()List.end()之前,如果你根據找到的原型使用find算法:

template<class InputIterator, class T> 
InputIterator find (InputIterator first, InputIterator last, const T& val) 

同時:

first, last Input iterators to the initial and final positions in a sequence. The range searched is [first,last), which contains all the elements between first and last, including the element pointed by first but not the element pointed by last.

此外,你發現情況不對:

if(find(List.begin(), List.end(), key) != List.end()) 
{           //^^^^^ 
    //if key exist, remove 
} 

在你的代碼,它會不斷消除,直到當地List是空的。

你刪除的功能應該是下面這樣的:

inline void HTable::remove(string key) 
{ 
    vector<list<string> >::iterator it; 
    for (it = List.begin(); it != List.end(); it ++) 
    { 

    if(find((*it).begin(), (*it).end(), key) != (*it).end()) 
    { 
     (*it).pop_back(); 
    } 
    } 
} 
+0

哎呀,我忘了改變這一點。我正在嘗試其他的東西。但即使當我把List.begin()放在第一位,我仍然收到同樣的錯誤 – 2013-04-10 23:45:49

+0

@bobGlenn我剛更新了它,請檢查。 – taocp 2013-04-10 23:47:48

+0

好的,太棒了!我試過,它的工作原理,但我只是覺得這個代碼,我沒有刪除任何東西。 – 2013-04-10 23:50:43

0

使用rbegin來咬得到,如果你想向後遍歷列表(如果你需要這個,是反向的迭代器 - 有時它可能是更好,更快:依賴於上下文):

for (std::list<...>::reverse_iterator it=list.rbegin(); it!=list.rend(); ++it) 

,您還可以使用自動:

for(auto it=list.rend(); it!=list.rbegn(); ++it) {...}

0

由於您通過查找確切的值從列表中刪除,因此讓標準模板庫幫助您更容易。

對於C++ 98,創建一個謂語對象,將檢查爲對象的平等:

struct string_equal 
{ 
    string_equal(const std::string& tgt) : target(tgt) 
    {} 

    bool operator()(const std::string& key) const 
    { 
     return key == target; 
    } 

    const std::string& target; 
}; 

void remove(const std::string& key) 
{ 
    // find the appropriate list in your vector 
    list<string>& List = get_correct_list_for_key(key); 

    list<string>::iterator new_end = std::remove_if(List.begin(), List.end(), string_equal(key)); 

    List.erase(new_end, List.end()); 
} 

在C++ 11,你可以這樣做更容易使用Lambda:

void remove(const std::string& key) 
{ 
    list<string>& List = get_correct_list_for_key(key); 

    auto new_end = std::remove_if(List.begin(), List.end(), 
    [&] (const std::string& target) -> bool { return target == key; }); 

    List.erase(new_end, List.end()); 
}