2013-10-28 42 views
0

我正在做一个关于使用向量的开放寻址散列表的项目。这个项目的一个方面是使用模板来允许用户定义矢量的类型。我已经实现了模板,如果我在编译之前创建了一个对象,它会起作用,但我无法弄清楚如何让用户在运行时决定类型。类模板,允许用户定义C++类型

该程序是面向对象的,并且类型必须传递给构造函数。起初我认为简单,如果陈述会起作用,但是我从那以后知道这不起作用。任何人都可以帮我解决这个问题吗?谢谢

#include <iostream> 
#include <string> 
#include <vector> 
using namespace std; 

template <class T> 
class OpenHash 
{ 
private: 
vector <T> hashTab; 
vector <int> emptyCheck; 
int hashF(string); 

public: 
OpenHash(int); 
int getVectorCap(); 
int addRecord (T); 
int sizeHash(); 
int find(T); 
int printHash(); 
int deleteEntry(T); 

}; 

template <class T> 
OpenHash<T>::OpenHash(int vecSize) 
{ 
hashTab.clear(); 
hashTab.resize(vecSize); 
emptyCheck.resize(vecSize); 
     for (int i=0; i < emptyCheck.capacity(); i++) 
     { 
     emptyCheck.at(i) = 0; 

     } 
} 

template <class T> 
int OpenHash<T>::getVectorCap() 
{ 

int cap = hashTab.capacity(); 
int capE = emptyCheck.capacity(); 
cout << cap << capE; 
return 0; 
} 

template <class T> 
int OpenHash<T>::hashF (string key) 
{ 
int ascii = 0, hasVal = 0; 

    for (int i = 0; i < key.size(); i++) 
     { 
      ascii += key[i]; 
     } 
hasVal = ascii % hashTab.capacity(); 
return hasVal; 
} 

template <class T> 
int OpenHash<T>::addRecord(T key) 
{ 
if (sizeHash() == emptyCheck.size()) 
{ 
    cout << "Your hash table is full cannot add any more records" << endl; 
} 

else 
{ 
    bool findPos = false; 

    for (int j=0; j<hashTab.capacity(); j++) 
    { 
     if (hashTab.at(j) == key) 
     { 
      cout << "Element ready exists in hashtable" << endl; 
      return 0; 
     } 

    } 
    int hashVal = hashF(key); 

     for (int i=hashVal; i<emptyCheck.capacity(); i++) 
     { 
      if (emptyCheck.at(i) == 0) 
      { 
       hashTab.at(i) = key; 
       emptyCheck.at(i) = 1; 
       cout << "Element added at" << '[' << i << ']' << endl; 
       findPos = true; 
       return 0; 
      } 
      else 
      { 
       cout << "Collision probing through..." << endl; 
      } 
     } 

     if (findPos == false) 
     { 

      for (int x=0; x<emptyCheck.capacity(); x++) 
      { 
       if (emptyCheck.at(x) == 0) 
       { 
        hashTab.at(x) = key; 
        emptyCheck.at(x) = 1; 
        cout << "Element added at" << '[' << x << ']' << endl; 
        findPos=true; 
        return 0; 
       } 
      } 
     cout << "Element could not be added" << endl; 

     } 


} 
return 1; 
} 

template <class T> 
int OpenHash<T>::sizeHash() 
{ 
int elementsFilled = 0; 

    for (int i = 0; i<emptyCheck.capacity(); i++) 
     { 
      if (emptyCheck.at(i) != 0) 
       { 
        elementsFilled++; 
       } 
     } 

return elementsFilled; 

} 

template <class T> 
int OpenHash<T>::find(T key) 
{ 
int hashVal = hashF(key); 
bool findLoop = false; 


for (int i=hashVal; i < hashTab.capacity(); i++) 
{ 

     if (hashTab.at(i) == key && emptyCheck.at(i) == 1) 
     { 
      cout << "Element found at position: " << '[' << i << ']' << endl; 
      cout << key << endl; 
      findLoop = true; 
      return 0; 
     } 

     else 
     { 
      cout << "Element not found at position! Probing through..." << endl; 
      } 


    }  

     if (findLoop == false) 
     { 


      for (int j = 0; j < hashTab.capacity(); j++) 
      { 

       if (hashTab.at(j) == key && emptyCheck.at(j) != 0) 
       { 
        cout << "Element found at position: " << '[' << j << ']' << endl; 
        cout << key << endl; 
        findLoop = true; 
        return 0; 
       } 

      } 
     cout << "Entry not found" << endl; 
     } 
return 1; 

} 

template <class T> 
int OpenHash<T>::deleteEntry(T toDel) 
{ 
int hashVal = hashF(toDel); 
bool foundDel = false; 

    for (int i = hashVal; i<hashTab.capacity(); i++) 
    { 
     if (hashTab.at(i) == toDel) 
     { 
      emptyCheck.at(i) = 0; 
      foundDel = true; 
      cout << "Entry deleted!" << endl; 
      return 0; 
     } 
    } 

     if (foundDel == false) 
     { 
      for (int j=0; j<hashTab.capacity(); j++) 
      { 
       if (hashTab.at(j) == toDel) 
       { 
        emptyCheck.at(j) = 0; 
        foundDel = true; 
        cout << "Entry deleted!" << endl; 
        return 0; 

       } 

      } 
     cout << "The member to delete was not found" << endl; 
     } 

return 1; 
} 

template <class T> 
int OpenHash<T>::printHash() 
{ 
if (sizeHash() == 0) 
{ 
    cout << "No elements filled to print!" << endl; 
} 

    for (int i=0; i<emptyCheck.capacity(); i++) 
    { 
     if (emptyCheck.at(i) != 0) 
      { 
       cout << "Record at:" << '[' << i << ']' << hashTab.at(i) << endl; 
      } 
    } 
return 0; 
} 

int main() 
{ 
    cout << "Please input the size of your HashTable" << endl; 
    int vecSize = 0; 
    cin >> vecSize; 
    OpenHash<string> newTable(vecSize); 

bool menu = true; 
char choice; 
while (menu == true)  
{ 
    cout << "Welcome to the open address hash table program, please input your choice:" << endl; 
    cin >> choice; 

     if (choice == 'a') 
     { 
      cout << "Please type in the record you wish to add:" << endl; 
      string rec; 
      getline(cin, rec); 
     newTable.addRecord(rec); 
     } 
     if (choice == 's') 
     { 
      cout << "Number of elements filled: " << newTable.sizeHash() << endl; 
     } 
     if (choice == 'f') 
     { 
      cout << "Please enter the string you wish to find" << endl; 
      string key; 
      getline(cin, key) 
      newTable.find(key); 
     } 
     if (choice == 'p') 
     { 
      cout << "Printing table..." << endl; 
      newTable.printHash(); 

     } 
     if (choice == 'd') 
     { 
      cout << "Please input the item you wish to delete:" << endl; 
      string toDel; 
      getline(cin, toDel) 
      newTable.deleteEntry(toDel); 
     } 

     if (choice == 'x') 
     { 
      cout << "Thankyou" << endl; 
      menu = false; 
     } 
} 

return 0; 
} 
+0

类型不传递给构造函数; *参数*(当然,它们具有类型,但在语言意义上它们本身不是“类型”)。显示您现有的代码将比您告诉我们更多的清晰度。这听起来像是你有一个可由用户选择的可配置类型库,但这纯粹是没有任何支持的猜测。 – WhozCraig

+0

请显示代码! –

回答

2

模板在编译期间“确定”。它们不能在运行时动态决定。

如果你想支持某些类型(例如intdoublechar等),你可以明确地在程序中声明它们,它们会被编译,但一样支持(或其他您在仅使用类型您的程序)将可供用户“挑选”:

template<typename T> 
class MyTemplateClass { ... }; 

class template MyTemplateClass<int>; 
class template MyTemplateClass<double>; 
class template MyTemplateClass<char>; 

int main() 
{ 
    // if user wants to create a new int version: 
    MyTemplate<int> myInt; 
    // etc ... 
    return 0; 
}