数据正确放置在数组中,但在打印数组时不存在

Data placed into array correctly but is not there when array is printed

本文关键字:数组 打印 不存在 数据      更新时间:2023-10-16

我正在实现自己的哈希表,遇到了以下问题:当我将节点插入表中时,当我循环遍历数组时,它们没有打印出来。我使用数组数组作为底层数据结构,逻辑如下:

  • 我将节点传递给插入函数。此函数基于我的节点中的数据类型,调用提供的相应哈希函数由C++ STL
  • 然后,我修改由大小返回的哈希值我的哈希表并使用它来确定放置哪个数组节点。
  • 我还有一个布尔数组数组(与我的相同大小哈希表(,我用来检查哈希中的特定位置是否表中已包含数据。
  • 如果是这样,我只是继续循环直到找到一个空白点。

就像我之前说的,问题是数据被正确地输入到数组中(我已经用 print 语句检查过(,但是当我打印数组时,什么都没有输出。我还检查了我的对象是否正确构造(再次,使用 print 语句(,但一切看起来都很好。我在下面包含了完整的代码。任何帮助将不胜感激!

        ///////START OF NODE.H///////////
        #ifndef NODE_H
        #define NODE_H
        #include <iostream>
        template <typename T>
        class HashTable;
        template <typename T>
        class Node
        {
            friend class HashTable<T>;
            private:
                T data;
            public:
                Node(T Data): data(Data)
                {
                    std::cout << "In the node constructor" << std::endl;
                }
                Node() 
                {
                    decltype(data) {};
                }
                T getData() const
                {
                    return data;
                }
        };
        #endif
        //////////////////////END OF NODE.H////////////////////


        /////START OF HASHTABLE.H///////
        #ifndef HASHTABLE_H
        #define HASHTABLE_H
        #include "Node.h"
        #include <iostream>
        #include <array>
        #include <functional>
        #include <typeinfo>
        #include <string>
        const int TABLE_SIZE=5;
        template <typename T>
        class HashTable
        {
            private:
                std::array<std::array<Node<T>, TABLE_SIZE>, TABLE_SIZE> hashTable;
                std::array<std::array<bool, TABLE_SIZE>, TABLE_SIZE> spots;
            public:
                HashTable()
                {
                    for(int index=0;index<spots.size();++index)
                    {
                        for(int position=0;position<spots.at(index).size();++position)
                        {
                            spots.at(index).at(position)=false;
                        }
                    }
                }
                int hashFunction(Node<T> Node)
                {
                    auto key=Node.getData();
                    std::hash<decltype(Node.getData())> hash_function {};
                    int hash=hash_function(key);
                    if(hash < 0)
                    {
                        hash*=-1;
                    }
                    //std::cout << "The hash value return by the STL hash function for the key " << key << " is " << hash << std::endl;
                    if(hash > TABLE_SIZE)
                    {
                        hash%=TABLE_SIZE;
                    }
                    std::cout << "The hash value for the key " << key << " is " << hash << std::endl;
                    return hash;
                }
                void insert(Node<T> Node)
                {
                    int hashValue=hashFunction(Node);
                    auto location=hashTable.at(hashValue);
                    std::cout << "Going to insert " << Node.getData() << std::endl;
                    for(int index=0;index<location.size();++index)
                    {
                        if(spots.at(hashValue).at(index)==false)
                        {
                            std::cout << "Found a spot that is not taken!" << std::endl;
                            std::cout << "The size of the data at the spot in the array before we insert is: " << location.at(index).getData().size() << std::endl;
                            location.at(index)=Node;
                            std::cout << "The size of the data at the spot in the array after we insert is: " << location.at(index).getData().size() << std::endl;
                            std::cout << "The data that is in the spot in the array: " << location.at(index).getData() << std::endl;
                            std::cout << std::endl;
                            spots.at(hashValue).at(index)=true;
                            break;
                        }
                    }
                }
                bool contains(Node<T> Node)
                {
                    int hashValue=hashFunction(Node);
                    auto location=hashTable.at(hashValue);
                    auto result=find_if(begin(location), end(location), [Node] (const auto & element) {return element.getData()==Node.getData();});
                    if(result!=end(location))
                    {
                        return true;
                    }
                    return false;
                }
                int getSize() const
                {
                    int size {};
                    for(int index=0;index<hashTable.size();++index)
                    {
                        size+=hashTable.at(index).size();
                    }
                    return size;
                }
                void print()
                {
                    std::cout << "In the print function" << std::endl;
                    for(int index=0;index<hashTable.size();++index)
                    {
                        //std::cout << hashTable.at(index).size() << std::endl;
                        for(int position=0;position<hashTable.at(index).size();++position)
                        {                   
                            std::cout << hashTable.at(index).at(position).getData().size() << std::endl;
                        }
                    }
                    /*
                    for(int index=0;index<spots.size();++index)
                    {
                        for(int position=0;position<spots.at(index).size();++position)
                        {
                            if(spots.at(index).at(position)==true)
                            {
                                std::cout << "There should be some data here" << std::endl;
                            }
                        }
                    }
                    */
                }
        };
        #endif
        ////////////END OF HASHTABLE.H//////////

       ////////////START OF MAIN.CPP///////////
             #include "HashTable.h"
             #include <cstdlib>
             #include <random>
             #include <algorithm>
             using namespace std;                 
             int main()
             {
                HashTable<string> hash_table;
                hash_table.insert(Node<string>("Java"));
                hash_table.insert(Node<string>("C++"));
                hash_table.insert(Node<string>("C#"));
                hash_table.insert(Node<string>("Latex"));
                hash_table.insert(Node<string>("Python"));
             }
        /////////////END OF MAIN.CPP/////////////

以下行的insert(Node<T> Node)函数中有一个错误:

    auto location=hashTable.at(hashValue);
    //...
    location.at(index) = Node;

location应该是参考而不是副本。 正在发生的事情是你正在对本地location进行更改,而不是哈希表使用的实际location。 因此,您的任何更改都不会"坚持"。

上面的行应该是这样的:

    auto& location=hashTable.at(hashValue);  // <-- note that auto is a reference
    //...
    location.at(index) = Node;  

现在,您将返回的引用分配给引用。

此外,我强烈建议您使用调试器,因为如果您单步执行代码以查看正在执行的操作,则可以轻松诊断此错误。

HashTable::insert这一

auto location = hashTable.at(hashValue);

复制Node。然后,在副本中操作并存储,而不是hashTable中的节点。获取对节点的引用

auto & location = hashTable.at(hashValue);

应该修复它。