C++ Help Please !!

Discussion in 'Programming' started by sgrewal1, Nov 27, 2009.

  1. #1
    I have finished first part of my project but for the second part I need to implement a chained hash table in the following code.
    no need to code erase function...
    So, please help me....



    #include <string>
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <list>
    #include <stdexcept>
    #include <functional>

    using std::cerr;
    using std::cout;
    using std::string;
    using std::vector;
    using std::endl;
    using std::eek:stringstream;

    template <class I, class LessThan = std::less<I> >
    class Valli {
    class Cell; //forward declaration of nested class is OK only within class!
    public:
    class iterator;
    class const_iterator;
    private:
    friend class Cell;
    friend class iterator;
    friend class const_iterator;

    LessThan lessThan;
    Cell* dummyHead; //used only to make ->prev->next legal for 1st real node
    Cell* dummyEnd; //used similarly to speed insert for new max item
    vector<Cell*>* mileposts;
    size_t ratio;
    size_t numItems;
    size_t refreshTarget;
    //vector<size_t>* segmentSizes;

    class Cell { //doubly linked
    friend class iterator;
    friend class const_iterator;
    friend class Valli; //ANSI made this necessary in 1998
    I data;
    Cell* next;
    Cell* prev;
    Cell() : data(I()), next(NULL), prev(NULL) { }
    Cell(const I& item, Cell* gnext, Cell* gprev)
    : data(item), next(gnext), prev(gprev) { }
    virtual ~Cell() { }
    };

    public:
    class iterator {
    friend class Valli;
    friend class Cell; //needed?
    friend class const_iterator; //needed! (tho not on timberlake...)
    const Valli<I, LessThan>* holder;
    Cell* curr;
    iterator(const Valli<I, LessThan>* const gholder, Cell* gcurr)
    : holder(gholder), curr(gcurr) { }

    public:
    I& operator*() const {
    if (curr != holder->dummyEnd) {
    return curr->data;
    } else {
    cout << holder->str();
    throw std::invalid_argument("Attempt to de-reference the end");
    }
    }
    iterator& operator++() {
    curr = curr->next;
    return *this;
    }
    iterator operator++(int x) {
    iterator old = *this;
    curr = curr->next;
    return old;
    }
    bool operator==(const iterator& other) const {
    return curr == other.curr;
    }
    bool operator!=(const iterator& other) const {
    return curr != other.curr;
    }
    };

    class const_iterator {
    friend class Valli;
    friend class Cell; //needed?
    //Note asymmetry: in STL "iterator" has no operator==(const_iterator&)
    //Hence const_iterators can only be compared on LHS with iterators, i.e.
    //citr == itr not itr == citr, and const_iterator doesn't friend iterator
    const Valli<I, LessThan>* holder;
    Cell* curr;
    const_iterator(const Valli<I, LessThan>* const gholder, Cell* gcurr)
    : holder(gholder), curr(gcurr) { }
    public:
    const I& operator*() const {
    if (curr != holder->dummyEnd) {
    return curr->data;
    } else {
    throw std::invalid_argument("Attempt to de-reference the end");
    }
    }
    const_iterator& operator++() {
    curr = curr->next;
    return *this;
    }
    const_iterator operator++(int x) {
    const_iterator old = *this;
    curr = curr->next;
    return old;
    }
    bool operator==(const const_iterator& other) const {
    return curr == other.curr;
    }
    bool operator!=(const const_iterator& other) const {
    return curr != other.curr;
    }

    /** Next members needed too---following convention that in any
    comparison with a const_iterator, the const_iterator goes on left.
    */
    bool operator==(const iterator& other) const {
    return curr == other.curr;
    }
    bool operator!=(const iterator& other) const {
    return curr != other.curr;
    }

    };



    public:

    Valli()
    : lessThan(LessThan())
    , dummyHead(new Cell())
    , dummyEnd(new Cell())
    //, tail(head)
    , mileposts(new vector<Cell*>())
    , ratio(20)
    , numItems(0)
    , refreshTarget(40)
    //, segmentSizes(new vector<size_t>())
    {
    dummyHead->next = dummyEnd;
    dummyEnd->prev = dummyHead;
    mileposts->push_back(dummyHead->next); //which == dummyEnd
    mileposts->push_back(dummyEnd);
    //segmentSizes->push_back(0); //just 1 segment
    }

    Valli(size_t gratio)
    : lessThan(LessThan())
    , dummyHead(new Cell())
    , dummyEnd(new Cell())
    //, tail(head)
    , mileposts(new vector<Cell*>())
    , ratio(gratio)
    , numItems(0)
    , refreshTarget(2*gratio)
    //, segmentSizes(new vector<size_t>())
    {
    dummyHead->next = dummyEnd;
    dummyEnd->prev = dummyHead;
    mileposts->push_back(dummyHead->next); //which == dummyEnd
    mileposts->push_back(dummyEnd);
    //segmentSizes->push_back(0); //just 1 segment
    }

    virtual ~Valli() { //mainly cannibalized from SLIst!
    while (dummyHead != NULL) {
    Cell* delendum = dummyHead;
    dummyHead = delendum->next;
    delete(delendum);
    }
    //delete(head);
    delete(mileposts); // since we had pointer-to-vector
    }
    /** Iterator to first list data that doesn't compare < item
    Will be first data if item is new min, end() if item is new max.
    On empty container, j = 1, i = 0, so curr == limit and end() is ret.
    */
    iterator lower_bound(const I& item) const {
    size_t j = binsearch(item); //always j > 0
    int i = j-1;
    while (i > 0 && !lessThan(mileposts->at(i)->data , item)) {
    i--;
    }
    Cell* limit = mileposts->at(j);
    Cell* curr = mileposts->at(i);
    while (curr != limit && lessThan(curr->data , item)) {
    curr = curr->next;
    }
    return iterator(this, curr);
    }

    /** Pointer to first item that compares >, or end-NULL if nonesuch.
    */
    iterator upper_bound(const I& item) const {
    Cell* curr = mileposts->at(binsearch(item)); //always i > 0
    while (curr != dummyHead && lessThan(item , curr->data)) {
    curr = curr->prev;
    }
    return iterator(this, curr->next);
    }


    /** Add item, maintaining CLASS INV: linked list is sorted by lessThan.
    Adds at first permissible location, does not check for duplicates.
    Refreshes if segment size has grown to next multiple of r.
    */
    iterator insert(const I& item) {
    iterator itr = lower_bound(item); //calls binary search
    itr = insert(itr, item);
    numItems++;
    if (numItems >= refreshTarget) {
    refresh();
    refreshTarget = 2*numItems;
    } else if (itr.curr == dummyHead->next) {
    mileposts->at(0) = itr.curr;
    }
    return itr;
    }

    /** Iterator to first stored item that compares <> to item,
    end() if no such item. NOTE that end() is a const_iterator since
    this method is "const", so end() must be on the LHS of the comparison!
    */
    iterator find(const I& item) const {
    iterator itr = lower_bound(item);
    if (end() == itr || item < *itr) {
    //return end();
    return iterator(this, mileposts->back());
    } else {
    return itr;
    }
    }


    void erase(iterator itr) {
    Cell* delendum = itr.curr;
    size_t i = binsearch(*itr); // throws exception if itr == end
    size_t j = i-1;
    bool refreshFlag = false;
    while (j >= 0 && !lessThan(mileposts->at(j)->data , *itr)) {
    if (mileposts->at(j) == delendum) {
    refreshFlag = (mileposts->at(j+1) == delendum->next);
    mileposts->at(j) = delendum->next;
    break; //out of while loop
    }
    }
    delendum->prev->next = delendum->next;
    delendum->next->prev = delendum->prev; //cell now unlinked
    delete(delendum);
    numItems--;
    if (refreshFlag) {
    refresh();
    }
    }

    iterator begin() {
    return iterator(this, dummyHead->next);
    }
    iterator end() {
    return iterator(this, dummyEnd);
    }

    const_iterator begin() const {
    return const_iterator(this, dummyHead->next);
    }
    const_iterator end() const {
    return const_iterator(this, dummyEnd);
    }

    size_t size() const {
    return numItems;
    }
    bool empty() const {
    return numItems == 0;
    }

    void refresh(size_t newRatio) {
    mileposts->clear();
    Cell* curr = dummyHead->next;
    size_t count = 0;
    while (curr != dummyEnd) {
    if (count % newRatio == 0) {
    mileposts->push_back(curr); //copy
    }
    curr = curr->next;
    count++;
    }
    mileposts->push_back(curr); // pushes back dummyEnd
    }
    void refresh() { refresh(this->ratio); }
    string str() const {
    string str = " start \n";

    str = str + " | \n"
    + " | \n"
    + " V \n";
    //iterator itr = begin();
    Cell* curr = mileposts->at(0);
    size_t i = 0;
    string arr, num;
    while (curr != dummyEnd) {
    // str = str + "[o | o]--->" + current->item->toString() + "\n"
    // causes Seg Fault if item is a null pointer.
    if (i < mileposts->size() && curr == mileposts->at(i)) {
    arr = "-->";
    ostringstream oss;
    oss << segmentSize(i);
    num = oss.str();
    i++;
    } else {
    arr = " ";
    num = "";
    }
    str = str + arr + "[o | o]--->" + (curr->data).str() + "\n"
    + " | " + num + "\n"
    + " | \n"
    + " V \n";
    curr = curr->next;
    }
    arr = (curr == dummyEnd) ? "-->" : " ";
    str += arr + "end(), here NULL\n";
    return str;
    }

    /*-------------------------------------------------------------------------
    Private Utility Methods.
    *///-----------------------------------------------------------------------

    private:
    /** Insert before cell "pos" is on.
    */
    iterator insert(const iterator& pos, const I& item) {
    pos.curr->prev = pos.curr->prev->next = new Cell(item,
    pos.curr, pos.curr->prev);
    return iterator(this, pos.curr->prev);
    }

    /** Return min i such that mileposts->at(i)'s item is > argument item
    This includes end()---implicitly end()'s item is a super-max. Hence
    INV: left's item <= item < right's item.
    */
    size_t binsearch(const I& item) const {
    size_t left = 0;
    size_t right = mileposts->size() - 1; //initially dummyEnd
    while (right - left > 1) {
    size_t mid = (left + right) / 2; // INV: left < mid < right
    if (item < mileposts->at(mid)->data) {
    right = mid;
    } else {
    left = mid;
    }
    }
    return right;
    }


    /** Distance from mileposts->at(i) to mileposts->at(i+1), or to end().
    */
    size_t segmentSize(size_t i) const {
    if (i >= mileposts->size() || mileposts->at(i) == dummyEnd) {
    return 0;
    } // else
    Cell* head = mileposts->at(i);
    Cell* stop = mileposts->at(i+1); //might be end()
    size_t count = 0;
    while (head != stop) {
    count++;
    head = head->next;
    }
    return count;
    }


    }; //end of class Valli.
     
    sgrewal1, Nov 27, 2009 IP
  2. NeoCambell

    NeoCambell Peon

    Messages:
    456
    Likes Received:
    6
    Best Answers:
    0
    Trophy Points:
    0
    #2
    Sorry I'm not clear. What's the help you need?
     
    NeoCambell, Dec 5, 2009 IP
  3. sgrewal1

    sgrewal1 Peon

    Messages:
    10
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #3
    I need to implement a hash table into it using a hash function....and 2 template parameters/.....
     
    sgrewal1, Dec 5, 2009 IP
  4. organicCyborg

    organicCyborg Peon

    Messages:
    330
    Likes Received:
    8
    Best Answers:
    0
    Trophy Points:
    0
    #4
    So... what did you try that didn't work?
     
    organicCyborg, Dec 6, 2009 IP
  5. ankit_frenz

    ankit_frenz Active Member

    Messages:
    1,111
    Likes Received:
    41
    Best Answers:
    0
    Trophy Points:
    63
    #5
    explain whats the exact error you are getting or issues..no one can dig that huge code for free mate :)
     
    ankit_frenz, Dec 6, 2009 IP
  6. mindblaster

    mindblaster Peon

    Messages:
    77
    Likes Received:
    0
    Best Answers:
    0
    Trophy Points:
    0
    #6
    true says :D:D:D
     
    mindblaster, Dec 15, 2009 IP