Вставка объекта в хеш-таблицу… по какой-то причине не позволит?

0

Я разрабатываю простую программу, которая берет объект класса Symbol, который я определил и вставляет в HashTable. Мне был предоставлен файл HashTable.h, полученный из нашего учебника, и, как вы увидите, он предназначен для обработки любого объекта.

Я пытаюсь вставить свой объект через:

hashtable.insert(&temp) //where temp is the object 

Однако я получаю следующие ошибки:

    Driver.cpp: In function 'int main()':
    Driver.cpp:127:27: error: no matching function for call to 'HashTable<Symbol>::insert(Symbol*)'
    Driver.cpp:127:27: note: candidates are:
    In file included from Driver.cpp:12:0:
    SeperateChaining.h:50:10: note: bool HashTable<HashedObj>::insert(HashedObj&) [with HashedObj = Symbol]
    SeperateChaining.h:50:10: note:   no known conversion for argument 1 from 'Symbol*' to 'Symbol&'
    SeperateChaining.h:72:10: note: bool HashTable<HashedObj>::insert(HashedObj&&) [with HashedObj = Symbol]
    SeperateChaining.h:72:10: note:   no known conversion for argument 1 from 'Symbol*' to 'Symbol&&'

Не могли бы вы, ребята, взглянуть?

EDIT: Когда я пытаюсь вставить по стоимости, как многие из вас предложили, я возвращаю тонну мусора, но разбираюсь в ошибках, есть два:

opt/local/include/gcc47/c++/bits/stl_algo.h:135:7: error: no match for 'operator==' in '__first.std::_List_iterator<_Tp>::operator*<Symbol>() == __val'

а также

opt/local/include/gcc47/c++/bits/stl_algo.h:135:7: error: no match for 'operator==' in '__first.std::_List_iterator<_Tp>::operator*<Symbol>() == __val' – 

Вот мой файл драйвера и файл hash table.h:

Driver.cpp:

    #include <iostream>
    #include <iomanip>
    #include <cassert>
    #include <fstream>
    #include <string>
    #include <vector>
    #include <time.h>
    #include <unistd.h>
    #include <map>
    #include <cstdlib>
    #include <cmath>
    #include "SeperateChaining.h"

    //#include "hash_chn.h"

    using namespace std;

    int TABLE_SIZE; //I know it a global, but it allows the Table Size to be taken in within main() and used in hash()

    size_t hash(const string & key);

    class Symbol
    {
    private:
        int key;
        int type;
        string data;
    public:
        const string & getData() const
        {
            return data;
        }
        int getType() 
        {
            return type;
        }
        int getKey()
        {
            return labs(key);
        }
        void setType(int Type)
        {   
            type = Type;
        }
        void setData(string Data)
        {
            data = Data;
        }
        void setKey(int Key)
        {
            key = Key;
        }
    };

    int main()
    {
        HashTable<Symbol> hashtable(TABLE_SIZE);
        Symbol temp;
        vector<Symbol> symbols;
        string s;
        int t;
        int hash_key_array[TABLE_SIZE]; //array to hold hash key values

        ifstream file;
        file.open("symbols.txt");

        if(!file)
        {
            cout << "System failed to open file.";
        }
        else
        {
            cout << "File successfully opened" << endl;
        }

        //for loop to read in the string name and the integer that follows the string name from symbols.txt
        while(file >> s)
        {
            temp.setData(s);
            file >> t;
            temp.setType(t);
            symbols.push_back(temp);
        }

        for(int i = 0; i < symbols.size(); i++)
        {
            cout << symbols[i].getData() << "\n";
            cout << symbols[i].getType() << "\n";
        }

        cout << "What would you like the table size to be?" << endl;
        cout << "Note: If the table size is greater than the number of objects" <<
        " in the symbols.txt file, it will inevitably throw a segmentation fault" << endl;
        cin >> TABLE_SIZE;

        for(int j = 0; j < TABLE_SIZE; j++)
        {
            temp.setData(symbols[j].getData());
            cout << temp.getData() << endl;

            temp.setType(symbols[j].getType());
            cout << temp.getType() << endl;

            temp.setKey(::hash(symbols[j].getData()));
            cout << "The key is: " << temp.getKey() << endl;

            cout << endl;

            hash_key_array[j] = temp.getKey();


            for (int i = 0; i < TABLE_SIZE; i++)
            {
                if (i != j)
                {
                    if (hash_key_array[i] == hash_key_array[j])
                    {
                        cout << endl;
                        cout << "Collision occurred at " << hash_key_array[i] << endl;
                        //rehash();
                        //cout << "The new key is: " << temp.getKey() << endl;
                        break;
                    }
                }
            }

        hashtable.insert(&temp); //problem is here


        }
    }

    size_t hash(const string & key)
    {
        size_t hashVal = 0;

        for(char ch : key)
        {
            hashVal = 37 * hashVal + ch;
        }
        return labs(hashVal);
    }

SeperateChaining.h:

#ifndef SEPARATE_CHAINING_H
#define SEPARATE_CHAINING_H

#include <vector>
#include <list>
#include <string>
#include <algorithm>
#include <functional>
//#include "Hash.h"
using namespace std;

// SeparateChaining Hash table class
//
// CONSTRUCTION: an approximate initial size or default of 101
//
// ******************PUBLIC OPERATIONS*********************
// bool insert( x )       --> Insert x
// bool remove( x )       --> Remove x
// bool contains( x )     --> Return true if x is present
// void makeEmpty( )      --> Remove all items

template <typename HashedObj>
class HashTable
{
  public:

    //Uses the whatever value table_size has
    //Otherwise, it will make a hash table of size 101
    explicit HashTable( int TABLE_SIZE )
    { 
        currentSize = 0;
        theLists.resize(TABLE_SIZE); 
    }

    bool contains( const HashedObj & x ) const
    {
        //represents the correct list in the hash table vector to start looking through
        auto & whichList = theLists[ myhash( x ) ];

        //returns whatever you wanted to search for in the table provided it is there
        return find( begin( whichList ), end( whichList ), x ) != end( whichList );
    }

    void makeEmpty( )
    {
        for( auto & thisList : theLists )
            thisList.clear( );
    }

    bool insert(HashedObj & temp )
    {
         //represents the correct list in the hash table vector to start looking through
        auto & whichList = theLists[myhash( temp )];

        //goes through the beginning and end of the list, and if it
        //doesn't get to the end, then it found the object you wanted to insert in the hash table already
        //prevents duplicate insertions
        if( find( begin( whichList ), end( whichList ), temp ) != end( whichList) )
            return false;

        //otherwise, it has gotten to the end of the list without finding a duplicate
        //and puts what you want to insert in the list
        whichList.push_back( temp );

        // Rehash; see Section 5.5
        if( ++currentSize > theLists.size( ) )
            rehash( );

        return true;
    }

    bool insert( HashedObj && x )
    {
        auto & whichList = theLists[ myhash( x ) ];      
        if( find( begin( whichList ), end( whichList ), x ) != end( whichList ) )
            return false;
        whichList.push_back( std::move( x ) );

            // Rehash; see Section 5.5
        if( ++currentSize > theLists.size( ) )
            rehash( );

        return true;
    }

    bool remove( const HashedObj & x )
    {
        //represents the correct list in the hash table vector to start looking through
        auto & whichList = theLists[ myhash( x ) ];

        //trying to find x within the list
        //the iterator points to the slot in the list that contains x
        auto itr = find( begin( whichList ), end( whichList ), x );

        //if it gets to the end of the list without finding what you want to remove, then it returns false
        if( itr == end( whichList ) )
        {
            return false;
        }


        //if it finds x, it removes it from the list
        whichList.erase( itr );
        --currentSize;
        return true;
    }

    /*
    void printTable()
    {
        for(int i=0; i < symbols.size(); i++)
        {
            cout << "The hash table contains: " << symbols[i] << endl;
        }
    }
    */

  private: 
     vector<list<HashedObj>> theLists;   // The array of Lists
     int  currentSize;

     void rehash( )
     {
         vector<list<HashedObj>> oldLists = theLists;

         // Creates new double-sized, empty table
         theLists.resize( nextPrime( 2 * theLists.size( ) ) );
         for( auto & thisList : theLists )
             thisList.clear( );

         // Copies the old table into the new table
         currentSize = 0;
         for( auto & thisList : oldLists )
             for( auto & x : thisList )
                 insert( std::move( x ) );
     }

     size_t myhash( const HashedObj & x ) const
     {
         static hash<HashedObj> hf;
         return hf( x ) % theLists.size( );
        }
  };

#endif
Теги:
hashtable

3 ответа

2

hashtable.insert(& Temp)

Вы должны вставлять по значению, а не по указателю. Удалите оператор &.

  • 0
    Я пробовал это, но я получаю страницы с большим количеством ошибок, и я понятия не имею, почему
  • 0
    @ user2704533 Ну, боюсь, вам придется понимать сообщения об ошибках, а не пытаться вслепую. Сосредоточьтесь на первой полученной ошибке и проигнорируйте остальные, которые, скорее всего, являются просто ошибками последующих действий!
Показать ещё 2 комментария
0
hashtable.insert(&temp);
                 ^

Вы пытаетесь вставить адрес temp. Вот что говорит эта ошибка:

note: bool HashTable :: insert (HashedObj &) [с HashedObj =

Символ] примечание: неизвестное преобразование для аргумента 1 из 'Символ *' в 'Символ и'

Существует версия insert которая принимает ссылку в качестве аргумента. Поэтому вместо указателя вставьте объект по значению:

hashtable.insert(temp);
0

Посмотрите на ошибки, которые вы получаете:

SeperateChaining.h:50:10: note: bool HashTable<HashedObj>::insert(HashedObj&) [with HashedObj = Symbol]
SeperateChaining.h:50:10: note:   no known conversion for argument 1 from 'Symbol*' to 'Symbol&'
SeperateChaining.h:72:10: note: bool HashTable<HashedObj>::insert(HashedObj&&) [with HashedObj = Symbol]
SeperateChaining.h:72:10: note:   no known conversion for argument 1 from 'Symbol*' to 'Symbol&&'

Это говорит вам, что вы вызываете insert с Symbol* и insert функции принимает либо Symbol& либо Symbol&&.

Итак, давайте посмотрим на код, который вы называете insert:

hashtable.insert(&temp); //problem is here

Разумеется, вы используете & который является address-of operator который будет принимать адрес temp, который имеет тип Symbol, возвращая ему указатель (что, конечно, относится к типу Symbol*). Таким образом, вы вызываете функцию с Symbol*, чего не ожидают функции.

Sidenote: у вашей реализации есть еще несколько проблем, которые вам нужно будет сортировать. Спросите себя, что temp и что делает HashTable класс делать с l- и ссылки г-значение Symbol, что он принимает?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню