删除列表中的结构元素

Erasing a struct element within a list

本文关键字:结构 元素 删除列 列表 删除      更新时间:2023-10-16

我要做的是从列表中删除一个元素。元素是结构体。我现在很难受。上面的例子不是针对结构元素的。我试图将键/值设置为默认值,但一旦我遍历数据,它就会打印空白,这意味着元素仍然存在。我需要把它完全去掉。下面是我的代码。

. h文件
#include<list>
#include<queue>
using namespace std;
template <typename K, typename V, int CAP>
class HashTable {
public:
    HashTable(int(*)(const K&));
    bool HashTable<K, V, CAP>::containsKey(const K& key) const;
    HashTable<K, V, CAP>& operator=(const HashTable<K, V, CAP>&);
    V& operator[](const K&); // setter
    V operator[](const K&) const;  // getter
    queue<K> keys() const;
    int size() const {return siz;};
    void deleteKey(const K&);
private: 
    int getIndex(const K& key) const;
    struct Node{K key; V value;}; 
    int(*hashCode)(const K&);
    list<Node> data[CAP];
    int cap;
    int siz;
};

这是我想要实现的删除函数。

template<typename K, typename V, int CAP>
inline void HashTable<K, V, CAP>::deleteKey(const K & key)
{
  typename list<Node>::iterator it; // getters need to use const_iterator
  for (int i = 0; i < CAP; i++)
  {
    for (it = data[i].begin(); it != data[i].end(); it++)
    {
      if (it->key == key)
      {
        // these are a few things I tried, I know this is not right.
         data[i].back().key = K();
         data[i].back().value = V();
         data[i].remove(key); // Error  C2664   'void std::list<HashTable<std::string,int,100>::Node,std::allocator<_Ty>>::remove(const _Ty &)':
                              // cannot convert argument 1 from 'const std::string' to 'const HashTable<std::string,int,100>::Node &'   10HashTable
      }
    }
  }
}

keystd::string,但列表中包含Node s。
同样,data[i].back()是列表的最后一个元素,而不是*it

可以使用erase删除迭代器对应的元素:

template<typename K, typename V, int CAP>
inline void HashTable<K, V, CAP>::deleteKey(const K & key)
{
  for (int i = 0; i < CAP; i++)
  {
    typename list<Node>::iterator it = data[i].begin();
    while (it != data[i].end())
    {
      if (it->key == key)
      {
         // Make 'it' a valid iterator to the next element
         it = data[i].erase(it);
      }
      else
      {
         // Only increment if we didn't erase
         it++;
      }
    }
  }
}

现在,在c++ 11中,以下内容应该足够了:

template<typename K, typename V, int CAP>
inline void HashTable<K, V, CAP>::deleteKey(const K & key)
{
  for (auto& bucket: data)
  {
      bucket.remove_if([&] (auto& item) { return item->key == key; });
  }
}

但是由于这是一个哈希表,因此data中的索引可能是key的哈希值,因此您可以将其转换为一行代码:

template<typename K, typename V, int CAP>
inline void HashTable<K, V, CAP>::deleteKey(const K & key)
{
    data[hashCode(key)].remove_if([&] (auto& item) { return item->key == key; });
}

或者,因为您只需要找到一个元素(您的键只映射到一个值),您可以稍微长一点,但更有效:

template<typename K, typename V, int CAP>
inline void HashTable<K, V, CAP>::deleteKey(const K & key)
{
    auto& bucket = data[hashCode(key)];
    auto it = std::find_if(bucket.begin(), 
                           bucket.end(), 
                           [&] (auto& item) { return item->key == key; });
    if (it != bucket.end())
    {
        bucket.erase(it);
    }
}

使用remove()的最后一次尝试几乎是正确的解决方案。你只需要使用迭代器来删除:

   data[i].remove(it);
   break;  // found the element, iterator is invalid anyway: exit loop

假设'key'是唯一的