非常令人费解的逻辑错误

时间:2013-12-06 03:21:09

标签: c++ linked-list logic hashtable semantics

问题

您好。我几个小时以来一直在努力解决我认为的逻辑错误。我正在尝试使用链表列表在c ++中创建一个哈希表。当尝试从哈希表中检索项目时,我经常会收到错误,表明该项目未包含在表格中,因此无法检索该项目。我一直盯着这段代码几个小时,我真的可以用一些新鲜的眼睛。谁能发现这里有什么问题?我为我提供的代码量道歉,但我真的很难确定问题所在。

注意:我对c ++很陌生,所以请放轻松我:)!

感谢您的任何意见!


哈希表

标题

#include "LinkedList.cpp"
#include <iostream>
//#include <string>
using namespace std;

template <typename E>
class HashTable
{
private:
    struct HashElement
    {
        E data;
        string key;

        friend bool operator>(HashElement lhs, HashElement rhs)
        {
            if (lhs.key > rhs.key) return true;
            else return false;
        }
    };
    const static int CAPACITY = 75;
    LinkedList<HashElement> table[CAPACITY];
    int totalElements;
    int hash(string);
public:
    HashTable();
    bool contains(string);
    void put(string, E);
    E get(string);
    friend ostream& operator<<(ostream& stream, const HashTable<E> table);
};

cpp文件

#include "HashTable.h"

template <typename E>
HashTable<E>::HashTable()
{
    for (int i = 0; i < CAPACITY; i++)
        table[i] = LinkedList<HashElement>();
    totalElements = 0;
}

template <typename E>
int HashTable<E>::hash(string key)
{
    int i = atoi(key.c_str());
    if (i < 0)
        i *= (-1);
    return (i % CAPACITY);
}

template <typename E>
bool HashTable<E>::contains(string key)
{
    bool result = false;
    table[hash(key)].resetIter();

    if(!table[hash(key)].isEmpty())
    {
        while(table[hash(key)].hasNext())
        {
            if(table[hash(key)].getNext().key == key)
            {
                result = true;
            }
        }
    }

    return result;
}

template <typename E>
void HashTable<E>::put(string key, E item)
{
    if(!contains(key))
    {
        HashElement temp;
        temp.key = key;
        temp.data = item;
        table[hash(key)].insertItem(temp);
        totalElements++;
    }

}

template <typename E>
E HashTable<E>::get(string key)
{
    E temp;
    HashElement elem;

    if(contains(key))
    {
        table[hash(key)].resetIter();
        while(table[hash(key)].hasNext())
        {
            elem = table[hash(key)].getNext();
            if(elem.key == key)
            {
                temp = elem.data;
            }
        }
        return temp;
    }
    else 
    {
        throw runtime_error("The item is not contained in the HashTable");
    }
}

链表

标题

#include <iostream>
using namespace std;

#if !defined (LINKEDLIST_H)
#define LINKEDLIST_H
template<typename T>
class LinkedList
{
private:

    struct Node
    {
        T data;
        Node* nptr;
    };

    Node *head, *iter;
    int size;

public:
    LinkedList ();
    LinkedList (const LinkedList<T> &);
    ~LinkedList ();
    const LinkedList& operator=(const LinkedList<T> &);
    bool isEmpty (void) const;
    void insertItem(T);    //add item in sorted order
    bool contains(T item);
    int getSize();
    bool hasNext();
    T getNext();
    void resetIter();
    friend ostream& operator<<(ostream& stream, const LinkedList<T> list)
    {
        Node *temp;
        temp = list.head;
        while(temp->nptr != NULL)
        {
            stream << temp->data << "\n";
            temp = temp->nptr;
        }
        stream << temp->data << endl;

        return stream;
    }
};
#endif

cpp文件

#include "LinkedList.h"

template<typename T>
LinkedList<T>::LinkedList()
{
    head = NULL;
    size = 0;
    iter = head;
}

template<typename T>
LinkedList<T>::LinkedList (const LinkedList  &rhs)
{
    Node *tmpPtr1, *tmpPtr2;

    tmpPtr1 = head;
    tmpPtr2 = rhs.head;
    size = rhs.size;

    if (tmpPtr1 != tmpPtr2)
    {
        while (tmpPtr1 != NULL)
        {
            head = head->nptr;
            delete tmpPtr1;
            tmpPtr1 = head;

        }

        tmpPtr1 = head;


        while (tmpPtr2 != NULL)
        {
            insertItem(tmpPtr2->data);
            tmpPtr2 = tmpPtr2->nptr;
        }
    }
}

template<typename T>
const LinkedList<T>& LinkedList<T>::operator= (const LinkedList &rhs)
{
    Node *tmpPtr1, *tmpPtr2;

    tmpPtr1 = head;
    tmpPtr2 = rhs.head;
    size = rhs.size;

    if (tmpPtr1 != tmpPtr2)
    {
        while (tmpPtr1 != NULL)
        {
            head = head->nptr;
            delete tmpPtr1;
            tmpPtr1 = head;

        }

        tmpPtr1 = head;

        while (tmpPtr2 != NULL)
        {
            insertItem(tmpPtr2->data);
            tmpPtr2 = tmpPtr2->nptr;
        }
    }
    return *this;
}

template<typename T>
void LinkedList<T>::insertItem(T item)
{
    Node *temp, *curr, *prev;
    temp = new Node;
    temp->data = item;
    temp->nptr = NULL;
    curr = head;
    prev = NULL;

    if(head != NULL)
    {
        while(temp->data > curr->data)
        {
            if(curr->nptr != NULL)
            {
                prev = curr;
                curr = curr->nptr;
            }
            else break;
        }

        if(curr->nptr == NULL)
        {
            curr->nptr = temp;
        }
        else
        {
            if(prev != NULL)
            {
                temp->nptr = curr;
                prev->nptr = temp;
            }
            else
            {
                temp->nptr = curr;
                head = temp;
            }
        }  
    }
    else 
    {
        head = temp;
    }
    size++;

}

template<typename T>
bool LinkedList<T>::contains(T item)
{
    Node *temp;
    temp = head;
    bool result = false;

    while(temp->nptr != NULL)
    {
        if (temp->data == item)
        {
            result = true;
            break;
        }
        temp = temp->nptr;
    }

    return result;
}

template<typename T>
bool LinkedList<T>::isEmpty() const
{
    return (head == NULL);
}

template<typename T>
int LinkedList<T>::getSize()
{
    return size;
}

template<typename T>
bool LinkedList<T>::hasNext()
{
    if(iter->nptr != NULL)
        return true;
    else
        return false;
}

template<typename T>
T LinkedList<T>::getNext()
{
    if(hasNext())
    {
        T result;
        result = iter->data;
        iter = iter->nptr;
        return result;
    }
    else
        throw runtime_error("List has no more elements, Use resetIter() to return to beginning\n");
}

template<typename T>
void LinkedList<T>::resetIter()
{
    iter = head;
}

template<typename T>
LinkedList<T>::~LinkedList()
{

    Node *tmpPtr = head;

    while (tmpPtr != NULL)
    {
        head = tmpPtr->nptr;
        delete tmpPtr;
        tmpPtr = head;
    }
}

测试文件

此文件仅用于测试此问题,我的最终驱动程序将有所不同。

#include <iostream>
//#include "LinkedList.cpp"
#include "HTTPlog.cpp"
#include "HashTable.cpp"
using namespace std;

int main()
{
    /* HASHTABLE TEST */
    HashTable<HTTPlog> table;
    HTTPlog names[6];
    names[0] = HTTPlog("Marcus", "Kre", 8, 22, 94);
    names[1] = HTTPlog("Devon", "Fla", 10, 6, 9);
    names[2] = HTTPlog("Larry", "Kre", 2, 1, 63);
    names[3] = HTTPlog("Mike", "Fer", 35, 32, 5);
    names[4] = HTTPlog("Mdkq", "Bir", 8, 3, 23);
    names[5] = HTTPlog("Tess", "Thi", 6, 6, 6);

    for(HTTPlog l: names)
    {
        table.put(l.getResourceName(), l);
    }
    cout << table.contains("Marcus") << table.contains("Devon") << table.contains("Larry") << table.contains("Mike") << table.contains("JSDlfjsl") << endl;
    cout << "Successfully checked contains" << endl;
    cout << table.get("Marcus") << table.get("Mdkq") << table.get("Test") <<  endl;
    cout << "Sccessfully got" << endl;
    return 0;
}

样本输出

这是此代码输出的示例

11110
Successfully checked contains
Name:       Marcus
Date:       Kre
Status Code:    8
Total Bytes:    22
Request Count:  94
Name:       Mdkq
Date:       Bir
Status Code:    8
Total Bytes:    3
Request Count:  23
libc++abi.dylib: terminating with uncaught exception of type std::runtime_error: The item is not contained in the HashTable
Abort trap: 6

1 个答案:

答案 0 :(得分:0)

    names[5] = HTTPlog("Tess", "Thi", 6, 6, 6);
    ...
    cout << table.get("Marcus") << table.get("Mdkq") << table.get("Test") <<  endl;

您插入“Tess”,但尝试“测试”。

另外,在你的哈希函数中:

int i = atoi(key.c_str());

我的字符串总是i = 0。根据文档,如果输入不是数字,则结果是未定义的。

希望这有助于您需要进行一些改进。