c++ - 生命游戏哈希表 .h 文件模板问题

标签 c++ key hashtable conways-game-of-life

我正在尝试使用我创建的实现文件来模拟康威的生命游戏,我已经取得了很好的进展,但不幸的是我遇到了一个令我困惑的错误。我认为问题在于我不知道如何正确编码模板化函数,无论如何,这是我的实现文件:

#include <list>

#ifndef HashTable_h
#define HashTable_h

using namespace std;

#define HASHTABLE_CAPACITY 1009

template <class DataType>
class HashTable
{
  public:
    HashTable(); // constructor
    bool insert(DataType &a); // insert function for inserting value of dataType into table
    bool retrieve(DataType &a); // retrieve function for retrieving value from table
    bool replace(DataType &a); // function for replacing the value from the table with the parameter
    bool remove(DataType& a);//removed function written and checked
    //int getSizeOf() const;
    void clear(); // for clearing the table
    int size() const;

  private:
    list<DataType> table[HASHTABLE_CAPACITY]; // static array
    int count;
    int currentIndex;
    typename list<DataType>::const_iterator it;
};

// constructor
template <class DataType>
HashTable<DataType>::HashTable()
{
  list<DataType> table[HASHTABLE_CAPACITY];
  count = 0;
  currentIndex = -1;
}

// retrieve function
template <class DataType>
bool HashTable<DataType>::retrieve(DataType &a)
{
  // get wrapped index
  int wrappedIndex = a.hashCode() % HASHTABLE_CAPACITY;
  if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;

  // if the array location isn't occupied, fail
  if (wrappedIndex < 0 || wrappedIndex >= HASHTABLE_CAPACITY || table[wrappedIndex].empty()) return false;

  // iterator for traversing table values
  typename list<DataType>::const_iterator it; 

  // if the keys match then replace the data
  // if a collision occurs then return false
  it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), a);
  if(it == table[wrappedIndex].end()) 
    return false; 
  a = *it;

  return true;
}

// overloaded operator function

// function for inserting values
template <class DataType>
bool HashTable<DataType>::insert(DataType &value)
{
  // get wrapped index
  int wrappedIndex = value.hashCode() % HASHTABLE_CAPACITY;
  if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;

  // iterator for traversing values in table
  typename list<DataType>::iterator it;

  // if array location is not "occupied", copy into array
  // else if keys match, replace the data
  if (table[wrappedIndex].empty())
  {
    table[wrappedIndex].push_back(value);
    count++;
    return true;
  }
  else
  {
    it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), value); 
    if (it != table[wrappedIndex].end()) *it = value;
    else {table[wrappedIndex].push_back(value); count++;}
  }

  return true;
}

// function for replacing values
template <class DataType>
bool HashTable<DataType>::replace(DataType &value)
{
  // get wrapped index
  int wrappedIndex = value.hashCode() % HASHTABLE_CAPACITY;
  if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;

  if(table[wrappedIndex].empty()) return false;

  // iterator for traversing the values in table
  typename list<DataType>::const_iterator it;

  it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), value);
  if(it == table[wrappedIndex].end()) return false;

  value = *it;
  table[wrappedIndex].erase(it);
  count--;

  return true;
}

template <class DataType>
bool HashTable<DataType>::remove(DataType &value)
{
  // get wrapped index
  int wrappedIndex = value.hashCode() % HASHTABLE_CAPACITY;
  if (wrappedIndex < 0) wrappedIndex = wrappedIndex + HASHTABLE_CAPACITY;

  if(table[wrappedIndex].empty()) return false;

  // iterator for traversing the values in table
  typename list<DataType>::iterator it;

  // if array location is not "occupied", copy into array
  // else if keys match, remove the data
  it = find(table[wrappedIndex].begin(), table[wrappedIndex].end(), value);
  if(it == table[wrappedIndex].end()) return false;

  value = *it;
  table[wrappedIndex].erase(it);
  count--;

  return true;
}


// function for clearing the table of it's values
template <class DataType>
void HashTable<DataType>::clear()
{
  count = 0;
  currentIndex = -1;

  for(int i = 0; i < HASHTABLE_CAPACITY; i++) 
    if( !table[i].empty()) table[i].clear();
}

template <class DataType>
int HashTable<DataType>::size() const
{
  return count;
}

#endif

这是实际的 Game Of Life 驱动程序文件:

// Lab 11b
#include <iostream>
using namespace std;

struct cell
{
  int value; // equal to 1, so 0,0 is not a blank
  int row; // any +/0/- value
  int col; // any +/0/- value

  bool operator==(const cell& c) const {return row == c.row && col == c.col;}
  bool operator<(const cell& c) const {return (1000000 * row + col) < (1000000 * c.row + c.col);}
  int hashCode() const {return 31 * row + col;}
};

#include "HashTable.h"
HashTable<cell> grid;
HashTable<cell> newGrid;

const int MINROW = -25;
const int MAXROW = 25;
const int MINCOL = -35;
const int MAXCOL = 35;

int neighborCount(int row, int col)
{
  cell temp;
  int count = 0;
  for (temp.row = row - 1; temp.row <= row + 1; temp.row++)
    for (temp.col = col - 1; temp.col <= col + 1; temp.col++)
      if (temp.row != row || temp.col != col)
        if (grid.retrieve(temp))
          ++count;
  return count;
}

void initialize()
{
  cout << "List the coordinates for living cells.\n";
  cout << "Terminate the list with a special pair -1 -1\n";

  cell temp;
  while (true)
  {
    cin >> temp.row >> temp.col;
    if (temp.row == -1 && temp.col == -1) break;
    grid.insert(temp);
  }
  cin.ignore();
}

void print()
{
  cell temp = {1};
  cout << "\nThe current Life configuration is:\n";
  for (temp.row = MINROW; temp.row <= MAXROW; temp.row++)
  {
    for (temp.col = MINCOL; temp.col <= MAXCOL; temp.col++)
      if (grid.retrieve(temp)) 
        cout << '*';
      else
        cout << ' ';
    cout << endl;
  }
  cout << endl;
}

void update()
{
  cell temp = {1};
  newGrid.clear();
  for (temp.row = MINROW; temp.row <= MAXROW; temp.row++)
    for (temp.col = MINCOL; temp.col <= MAXCOL; temp.col++)
      switch (neighborCount(temp.row, temp.col))
      {
        case 2:
          if (grid.retrieve(temp)) newGrid.insert(temp);
          break;
        case 3:
          newGrid.insert(temp);
          break;
      }

  grid = newGrid;    
};

int main()
{
  cout << "Welcome to Conway's game of Life\n";
  cout << "This game uses a grid in which\n";
  cout << "each cell can either be occupied by an organism or not.\n";
  cout << "The occupied cells change from generation to generation\n";
  cout << "according to the number of neighboring cells which are alive.\n";

  initialize();
  print();

  for (int i = 1; grid.size(); i++)
  {
    cout << "Generation " << i << ". Press ENTER to continue, X-ENTER to quit...\n";
    if (cin.get() > 31) break;
    update();
    print();
  }
  return 0;
}

当我尝试编译这些文件时,出现此错误:

In file included from GameOfLife.cpp:16:
HashTable.h: In member function ‘bool HashTable<DataType>::retrieve(DataType&) [with DataType = cell]’:
GameOfLife.cpp:32:   instantiated from here
HashTable.h:74: error: no matching function for call to ‘find(std::_List_iterator<cell>, std::_List_iterator<cell>, cell&)’
HashTable.h: In member function ‘bool HashTable<DataType>::insert(DataType&) [with DataType = cell]’:
GameOfLife.cpp:47:   instantiated from here
HashTable.h:117: error: no matching function for call to ‘find(std::_List_iterator<cell>, std::_List_iterator<cell>, cell&)’

这里可能出现什么问题?

最佳答案

您需要#include <algorithm>获取 std::find 。这大概就是您调用 find 时想要使用的内容。 。您应该避免using namespace std ,特别是在标题中。

关于c++ - 生命游戏哈希表 .h 文件模板问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13785898/

相关文章:

scala - 当键是一个只有第一个元素已知的元组时,如何获取 scala Map 值?

hashtable - Freemarker Hashtable<Integer, String>,按键迭代

c - 这个 foreach C 宏有多邪恶?

c++ - C 带有 char[] 的减法

c++ - 模板类和在 C++ 中使用带有混合参数的重载构造函数

带有 OR 运算符的 C++ if 语句无法正常工作

MySQL 错误 - 添加主键

c++ - Visual Studio 2013 Professional 链接器错误

javascript - 为什么这个 HTML/JavaScript 幻灯片的所有图像都没有改变?

c++ - 将哈希表重载为 vector 的 [] 运算符