2013-10-28 46 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; 
}