Avatar billede siul Nybegynder
07. maj 2003 - 12:14 Der er 12 kommentarer og
1 løsning

stack

Hej allesammen,
Hvordan modificerer man nedenstaaende stack implementation saa top funktionen returnerer en reference til top item? prototypen for top functionen aendres saaledes til: item& top(); Et test program til opgaven vil vaere en stor hjaelp.
Haaber at der en der kan hjaelpe mig.
Paa forhaand tak

#ifndef MAIN_SAVITCH_STACK2_H
#define MAIN_SAVITCH_STACK2_H
#include <cstdlib>  // Provides NULL and size_t
#include "node2.h" 

namespace main_savitch_7B
{
    template <class Item>
    class stack
    {
    public:
        // TYPEDEFS
        typedef std::size_t size_type;
        typedef Item value_type;
        // CONSTRUCTORS and DESTRUCTOR
        stack( ) { top_ptr = NULL; }
        stack(const stack& source);
        ~stack( ) { list_clear(top_ptr); }
        // MODIFICATION MEMBER FUNCTIONS
        void push(const Item& entry);
        void pop( );
        void operator =(const stack& source);
        // CONSTANT MEMBER FUNCTIONS
        size_type size( ) const
        { return main_savitch_6B::list_length(top_ptr); }
        bool empty( ) const { return (top_ptr == NULL); }
        Item top( ) const;
    private:
        main_savitch_6B::node<Item> *top_ptr;  // Points to top of stack
    };
}

#include "stack2.template" // Include the implementation
#endif

//********************************************************
// FILE: stack2.template
// TEMPLATE CLASS IMPLEMENTED: stack<Item> (see stack2.h for documentation)
// This file is included in the header file, and not compiled separately.
// INVARIANT for the stack class:
//  1. The items in the stack are stored in a linked list, with the top of the
//      stack stored at the head node, down to the bottom of the stack at the
//      final node.
//  2. The member variable top_ptr is the head pointer of the linked list.

#include <cassert>  // Provides assert
#include "node2.h"  // Node template class

namespace main_savitch_7B
{
    template <class Item>
    stack<Item>::stack(const stack<Item>& source)
    // Library facilities used: node2.h
    {
        main_savitch_6B::node<Item> *tail_ptr; // Needed for argument of list_copy

        list_copy(source.top_ptr, top_ptr, tail_ptr);
    }

    template <class Item>
    void stack<Item>::push(const Item& entry)
    // Library facilities used: node2.h
    {
        list_head_insert(top_ptr, entry);
    }

    template <class Item>
    void stack<Item>::pop( )
    // Library facilities used: cassert, node2.h
    {
        assert(!empty( ));
        list_head_remove(top_ptr);
    }
   
    template <class Item>
    void stack<Item>::operator =(const stack<Item>& source)
    // Library facilities used: node2.h
    {
        main_savitch_6B::node<Item> *tail_ptr; // Needed for argument of list_copy

        if (this == &source) // Handle self-assignment
            return;

        list_clear(top_ptr);
        list_copy(source.top_ptr, top_ptr, tail_ptr);
    }

    template <class Item>
    Item stack<Item>::top( ) const
    // Library facilities used: cassert
    {
        assert(!empty( ));
        return top_ptr->data( );
    }
}
Avatar billede olennert Nybegynder
07. maj 2003 - 12:26 #1
Hvis din kode virker som den er nu (hvor den returnerer en kopi af top-elementet), så er det bare at ændre typen af top, både i .h-filen og i .template filen.
Avatar billede olennert Nybegynder
07. maj 2003 - 12:28 #2
Med andre ord:

namespace main_savitch_7B
{
    template <class Item>
    class stack
    {
    public:
        // Meget slettet
        Item& top( ) const;
    private:
        main_savitch_6B::node<Item> *top_ptr;  // Points to top of stack
    };
}

namespace main_savitch_7B
{
    // Meget slettet
    template <class Item>
    Item& stack<Item>::top( ) const
    // Library facilities used: cassert
    {
        assert(!empty( ));
        return top_ptr->data( );
    }
}
Avatar billede olennert Nybegynder
07. maj 2003 - 12:30 #3
Og hvordan tester du så om det virker?

#include <stack2.h>

int main() {
  stack<int> my_stack;
  my_stack.push(1);
  // Check at my_stack.top() == 1
  my_stack.top() = 7;
  // Check at my_stack.top() == 7
  return 0;
}

Det at du både skal kunne checke top() og ændre i den gør at du faktisk har brug for top() i to udgaver. Både med og uden &, og lad være med at lave den const når den er med &.

}
Avatar billede siul Nybegynder
07. maj 2003 - 12:41 #4
Tak for dit svar, imponerende hurtigt. Jeg sidder lige med et andet project som har drillet i timevis, saa jeg vil vende tilbare senere, naar jeg har faaet kigget paa dit svar.
Endnu engang tak
Avatar billede siul Nybegynder
07. maj 2003 - 14:17 #5
Det virker desvarre ikke. Kan du muligvis compile det og de hvad der sker. Jeg har pasted to filer ind som ikke var med i foerste omgang, saa programmet skulle vaere klar til dig.
Jeg haaber at du kan finde fejlen.
Tak igen ;-)


node2.h refererer til denne fil:

#ifndef MAIN_SAVITCH_NODE2_H 
#define MAIN_SAVITCH_NODE2_H
#include <cstdlib>  // Provides NULL and size_t
#include <iterator>  // Provides iterator and forward_iterator_tag

namespace main_savitch_6B
{
    template <class Item>
    class node
    {
    public:
        // TYPEDEF
        typedef Item value_type;
        // CONSTRUCTOR
        node(const Item& init_data=Item( ), node* init_link=NULL)
            { data_field = init_data; link_field = init_link; }
        // MODIFICATION MEMBER FUNCTIONS
        Item& data( ) { return data_field; }
        node* link( ) { return link_field; }
        void set_data(const Item& new_data) { data_field = new_data; }
        void set_link(node* new_link) { link_field = new_link; }
        // CONST MEMBER FUNCTIONS
        const Item& data( ) const { return data_field; }
        const node* link( ) const { return link_field; }
    private:
        Item data_field;
        node *link_field;
    };

    // FUNCTIONS to manipulate a linked list:
    template <class Item>
    void list_clear(node<Item>*& head_ptr);

    template <class Item>
    void list_copy
        (const node<Item>* source_ptr, node<Item>*& head_ptr, node<Item>*& tail_ptr);

    template <class Item>
    void list_head_insert(node<Item>*& head_ptr, const Item& entry);

    template <class Item>
    void list_head_remove(node<Item>*& head_ptr);

    template <class Item>
    void list_insert(node<Item>* previous_ptr, const Item& entry);

    template <class Item>
    size_t list_length(const node<Item>* head_ptr);

    template <class NodePtr, class SizeType>
    NodePtr list_locate(NodePtr head_ptr, SizeType position);

    template <class Item>
    void list_remove(node<Item>* previous_ptr);
 
    template <class NodePtr, class Item>
    NodePtr list_search(NodePtr head_ptr, const Item& target);

    // FORWARD ITERATORS to step through the nodes of a linked list
    // A node_iterator of can change the underlying linked list through the
    // * operator, so it may not be used with a const node. The
    // node_const_iterator cannot change the underlying linked list
    // through the * operator, so it may be used with a const node.
    // WARNING:
    // This classes use std::iterator as its base class;
    // Older compilers that do not support the std::iterator class can
    // delete everything after the word iterator in the second line:

    template <class Item>
    class node_iterator
    : public std::iterator<std::forward_iterator_tag, Item>
    {
    public:
        node_iterator(node<Item>* initial = NULL)
        { current = initial; }
    Item& operator *( ) const
        { return current->data( ); }
    node_iterator& operator ++( ) // Prefix ++
        {
        current = current->link( );
        return *this;
        }
    node_iterator operator ++(int) // Postfix ++
        {
        node_iterator original(current);
        current = current->link( );
        return original;           
        }
    bool operator ==(const node_iterator other) const
        { return current == other.current; }
    bool operator !=(const node_iterator other) const
        { return current != other.current; }
    private:
    node<Item>* current;
    };

    template <class Item>
    class const_node_iterator
    : public std::iterator<std::forward_iterator_tag, const Item>
    {
    public:
        const_node_iterator(const node<Item>* initial = NULL)
        { current = initial; }
    const Item& operator *( ) const
        { return current->data( ); }
    const_node_iterator& operator ++( ) // Prefix ++
        {
        current = current->link( );
        return *this;
        }
    const_node_iterator operator ++(int) // Postfix ++
        {
        const_node_iterator original(current);
        current = current->link( );
        return original;
        }
    bool operator ==(const const_node_iterator other) const
        { return current == other.current; }
    bool operator !=(const const_node_iterator other) const
        { return current != other.current; }
    private:
    const node<Item>* current;
    };

}

#include "node2.template"
#endif

node2.template refererer til denne fil:
// FILE: node2.template
// IMPLEMENTS: The functions of the node template class and the
// linked list toolkit (see node2.h for documentation).
//
// NOTE:
//  Since node is a template class, this file is included in node2.h.
//  Therefore, we should not put any using directives in this file.
//
// INVARIANT for the node class:
//  The data of a node is stored in data_field, and the link in link_field.

#include <cassert>    // Provides assert
#include <cstdlib>    // Provides NULL and size_t

namespace main_savitch_6B
{
    template <class Item>
    void list_clear(node<Item>*& head_ptr)
    // Library facilities used: cstdlib
    {
    while (head_ptr != NULL)
        list_head_remove(head_ptr);
    }

    template <class Item>
    void list_copy(
    const node<Item>* source_ptr,
    node<Item>*& head_ptr,
    node<Item>*& tail_ptr
    )
    // Library facilities used: cstdlib
    {
    head_ptr = NULL;
    tail_ptr = NULL;

    // Handle the case of the empty list
    if (source_ptr == NULL)
        return;   

    // Make the head node for the newly created list, and put data in it
    list_head_insert(head_ptr, source_ptr->data( ));
    tail_ptr = head_ptr;
   
    // Copy rest of the nodes one at a time, adding at the tail of new list
    source_ptr = source_ptr->link( );
        while (source_ptr != NULL)
    {
        list_insert(tail_ptr, source_ptr->data( ));
        tail_ptr = tail_ptr->link( );
        source_ptr = source_ptr->link( );
    }
    }
   
    template <class Item>
    void list_head_insert(node<Item>*& head_ptr, const Item& entry)
    {
    head_ptr = new node<Item>(entry, head_ptr);
    }

    template <class Item>
    void list_head_remove(node<Item>*& head_ptr)
    {
    node<Item> *remove_ptr;

    remove_ptr = head_ptr;
    head_ptr = head_ptr->link( );
    delete remove_ptr;
    }

    template <class Item>
    void list_insert(node<Item>* previous_ptr, const Item& entry)
    {
    node<Item> *insert_ptr;
   
    insert_ptr = new node<Item>(entry, previous_ptr->link( ));
    previous_ptr->set_link(insert_ptr);
    }

    template <class Item>
    size_t list_length(const node<Item>* head_ptr)
    // Library facilities used: cstdlib
    {
    const node<Item> *cursor;
    std::size_t answer;
   
    answer = 0;
    for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))
        ++answer;
   
    return answer;
    }

    template <class NodePtr, class SizeType>
    NodePtr list_locate(NodePtr head_ptr, SizeType position)
    // Library facilities used: cassert, cstdlib
    {
    NodePtr cursor;
    SizeType i;
   
    assert(0 < position);
    cursor = head_ptr;
    for (i = 1; (i < position) && (cursor != NULL); ++i)
        cursor = cursor->link( );
    return cursor;
    }

    template <class Item>
    void list_remove(node<Item>* previous_ptr)
    {
    node<Item> *remove_ptr;

    remove_ptr = previous_ptr->link( );
    previous_ptr->set_link(remove_ptr->link( ));
    delete remove_ptr;
    }

    template <class NodePtr, class Item>
    NodePtr list_search(NodePtr head_ptr, const Item& target)
    // Library facilities used: cstdlib
    {
    NodePtr cursor;
   
    for (cursor = head_ptr; cursor != NULL; cursor = cursor->link( ))
        if (target == cursor->data( ))
        return cursor;
    return NULL;
    }
}
Avatar billede olennert Nybegynder
07. maj 2003 - 14:33 #6
Hvad mener du med virker ikke? Kan det ikke oversætte, eller giver det et andet resultat end du forventer?
Avatar billede siul Nybegynder
07. maj 2003 - 19:44 #7
Der er problemer med at .cpp filen. Foelgende fejl forekommer:
:\Documents and Setting\stack2.cpp(10) : error C2065: 'stack' : undeclared identifier
C:\Documents and Settings\stack2.cpp(10) : error C2062: type 'int' unexpected
C:\Documents and Settings\stack2.cpp(11) : error C2065: 'my_stack' : undeclared identifier
C:\Documents and Settings\stack2.cpp(11) : error C2228: left of '.push' must have class/struct/union type
C:\Documents and Setting\stack2.cpp(13) : error C2228: left of '.top' must have class/struct/union type
Error executing cl.exe.

stack2.obj - 5 error(s), 0 warning(s)
Avatar billede olennert Nybegynder
07. maj 2003 - 21:39 #8
Du har copy&pasted node2.h og node2.template, ikke? Men jeg vil også gerne se stack2.cpp, for det er der din oversætter finder fejlene.

Hvis du har copy&pasted mit forslag til en test (og det er det jeg gætter der sker), så mangler du sandsynligvis (i hvert fald)

using main_savitch_7B::stack; i stack2.cpp.
Avatar billede siul Nybegynder
07. maj 2003 - 22:18 #9
Det hjalp, men jeg sidder stadigvaek med denne fejl:
c:\documents and settings\stack2.h(62) : error C2065: 'list_clear' : undeclared identifier
Avatar billede siul Nybegynder
07. maj 2003 - 22:21 #10
ja, jeg brugte dit forslag til test bare for at svare paa dit forrige spoergsmaal
Avatar billede olennert Nybegynder
08. maj 2003 - 10:59 #11
list_clear kan jeg ikke se i noget af den kode du har pastet, så du kommer nok til at smide lidt mere ind. Det lader til at du prøver at bruge noget der hedder list_clear, som ikke er defineret nogetsteds.
Avatar billede siul Nybegynder
09. maj 2003 - 01:16 #12
Opgaven blev afleveret igaar og jeg er noedsaget til at arbejde paa mine andre 5 fag, saa jeg har maattet acceptere at jeg ikke finder ud af fejlen i foerste omgang.
Tak for hjaelpen, den har vaeret god
Avatar billede olennert Nybegynder
09. maj 2003 - 07:29 #13
Tak for point!

Jeg er nu alligevel nysgerrig over at se den del af koden hvor du bruger list_clear.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester