diff options
Diffstat (limited to 'chapter10')
| -rw-r--r-- | chapter10/animal.cxx | 149 | ||||
| -rw-r--r-- | chapter10/bag6.h | 94 | ||||
| -rw-r--r-- | chapter10/bintree.h | 169 | ||||
| -rw-r--r-- | chapter10/bintree.template | 100 | ||||
| -rw-r--r-- | chapter10/bt_class.h | 126 | ||||
| -rw-r--r-- | chapter10/useful.cxx | 80 | ||||
| -rw-r--r-- | chapter10/useful.h | 46 |
7 files changed, 764 insertions, 0 deletions
diff --git a/chapter10/animal.cxx b/chapter10/animal.cxx new file mode 100644 index 0000000..74f291b --- /dev/null +++ b/chapter10/animal.cxx @@ -0,0 +1,149 @@ +// FILE: animal.cxx
+// An animal-guessing program to illustrate the use of the binary tree toolkit.
+
+#include <cstdlib> // Provides EXIT_SUCCESS
+#include <iostream> // Provides cout
+#include <string> // Provides string class
+#include "bintree.h" // Provides the binary tree node functions
+#include "useful.h" // Provides eat_line, inquire (from Appendix I)
+using namespace std;
+using namespace main_savitch_10;
+
+// PROTOTYPES for functions used by this game program:
+void ask_and_move(binary_tree_node<string>*& current_ptr);
+// Precondition: current_ptr points to a non-leaf node in a binary taxonomy tree.
+// Postcondition: The question at the current node has been asked. The current
+// pointer has been shifted left (if the user answered yes) or right
+// (for a no answer).
+
+binary_tree_node<string>* beginning_tree( );
+// Postcondition: The function has created a small taxonomy tree. The return
+// value is the root pointer of the new tree.
+
+void instruct( );
+// Postcondition: Instructions for playing the game have been printed to the
+// screen.
+
+void learn(binary_tree_node<string>*& leaf_ptr);
+// Precondition: leaf_ptr is a pointer to a leaf in a taxonomy tree. The leaf
+// contains a wrong guess that was just made.
+// Postcondition: Information has been elicited from the user, and the tree has
+// been improved.
+
+void play(binary_tree_node<string>* current_ptr);
+// Precondition: current_ptr points to the root of a binary taxonomy tree with
+// at least two leaves.
+// Postcondition: One round of the animal game has been played, and maybe the
+// tree has been improved.
+
+
+int main( )
+{
+ binary_tree_node<string> *taxonomy_root_ptr;
+
+ instruct( );
+ taxonomy_root_ptr = beginning_tree( );
+ do
+ play(taxonomy_root_ptr);
+ while (inquire("Shall we play again?"));
+
+ cout << "Thank you for teaching me a thing or two." << endl;
+ return EXIT_SUCCESS;
+}
+
+void ask_and_move(binary_tree_node<string>*& current_ptr)
+// Library facilities used: bintree.h, string, useful.h
+{
+ cout << current_ptr->data( );
+ if (inquire(" Please answer:"))
+ current_ptr = current_ptr->left( );
+ else
+ current_ptr = current_ptr->right( );
+}
+
+binary_tree_node<string>* beginning_tree( )
+// Library facilities used: bintree.h, string
+{
+ binary_tree_node<string> *root_ptr;
+ binary_tree_node<string> *child_ptr;
+
+ const string root_question("Are you a mammal?");
+ const string left_question("Are you bigger than a cat?");
+ const string right_question("Do you live underwater?");
+ const string animal1("Kangaroo");
+ const string animal2("Mouse");
+ const string animal3("Trout");
+ const string animal4("Robin");
+
+ // Create the root node with the question �Are you a mammal?�
+ root_ptr = new binary_tree_node<string>(root_question);
+
+ // Create and attach the left subtree.
+ child_ptr = new binary_tree_node<string>(left_question);
+ child_ptr->set_left( new binary_tree_node<string>(animal1) );
+ child_ptr->set_right( new binary_tree_node<string>(animal2) );
+ root_ptr->set_left(child_ptr);
+
+ // Create and attach the right subtree.
+ child_ptr = new binary_tree_node<string>(right_question);
+ child_ptr->set_left( new binary_tree_node<string>(animal3) );
+ child_ptr->set_right( new binary_tree_node<string>(animal4) );
+ root_ptr->set_right(child_ptr);
+
+ return root_ptr;
+}
+
+void instruct( )
+// Library facilities used: iostream
+{
+ cout << "Let's play!" << endl;
+ cout << "You pretend to be an animal, and I try to guess what you are.\n";
+}
+
+void learn(binary_tree_node<string>*& leaf_ptr)
+// Library facilities used: bintree.h, iostream, string, useful.h
+{
+ string guess_animal; // The animal that was just guessed
+ string correct_animal; // The animal that the user was thinking of
+ string new_question; // A question to distinguish the two animals
+
+ // Set strings for the guessed animal, correct animal and a new question.
+ guess_animal = leaf_ptr->data( );
+ cout << "I give up. What are you? " << endl;
+ getline(cin, correct_animal);
+ cout << "Please type a yes/no question that will distinguish a" << endl;
+ cout << correct_animal << " from a " << guess_animal << "." << endl;
+ cout << "Your question: " << endl;
+ getline(cin, new_question);
+
+ // Put the new question in the current node, and add two new children.
+ leaf_ptr->set_data(new_question);
+ cout << "As a " << correct_animal << ", " << new_question << endl;
+ if (inquire("Please answer"))
+ {
+ leaf_ptr->set_left( new binary_tree_node<string> (correct_animal) );
+ leaf_ptr->set_right( new binary_tree_node<string> (guess_animal) );
+ }
+ else
+ {
+ leaf_ptr->set_left( new binary_tree_node<string> (guess_animal) );
+ leaf_ptr->set_right( new binary_tree_node<string> (correct_animal) );
+ }
+}
+
+void play(binary_tree_node<string>* current_ptr)
+// Library facilities used: bintree.h, iostream, string, useful.h
+{
+ cout << "Think of an animal, then press the return key.";
+ eat_line( );
+
+ while (!current_ptr->is_leaf( ))
+ ask_and_move(current_ptr);
+
+ cout << ("My guess is " + current_ptr->data( ) + ". ");
+ if (!inquire("Am I right?"))
+ learn(current_ptr);
+ else
+ cout << "I knew it all along!" << endl;
+}
+
diff --git a/chapter10/bag6.h b/chapter10/bag6.h new file mode 100644 index 0000000..8959658 --- /dev/null +++ b/chapter10/bag6.h @@ -0,0 +1,94 @@ +// FILE: bag6.h (part of the namespace main_savitch_10)
+// TEMPLATE CLASS PROVIDED: bag<Item>
+// (a container template class for a collection of items)
+//
+// TYPEDEFS for the bag<Item> class:
+// bag<Item>::value_type
+// bag<Item>::value_type is the data type of the items in the bag. It may
+// be any of the C++ built-in types (int, char, etc.), or a class with a
+// default constructor, a copy constructor, an assignment operator, and a
+// less-than operator forming a strict weak ordering.
+//
+// bag<Item>::size_type
+// bag<Item>::size_type is the data type of any variable that keeps track
+// of how many items are in a bag.
+//
+// CONSTRUCTOR for the bag<Item> class:
+// bag( )
+// Postcondition: The bag is empty.
+//
+// MODIFICATION MEMBER FUNCTIONS for the bag<Item> class:
+// size_type erase(const Item& target)
+// Postcondition: All copies of target have been removed from the bag. The
+// return value is the number of copies removed (which could be zero).
+//
+// bool erase_one(const Item& target)
+// Postcondition: If target was in the bag, then one copy of target has been
+// removed from the bag; otherwise the bag is unchanged. A true return value
+// indicates that one copy was removed; false indicates that nothing was
+// removed.
+//
+// void insert(const Item& entry)
+// Postcondition: A new copy of entry has been inserted into the bag.
+//
+// void operator +=(const bag& addend)
+// Postcondition: Each item in addend has been added to this bag.
+//
+// CONSTANT MEMBER FUNCTIONS for the bag<Item> class:
+// size_type size( ) const
+// Postcondition: Return value is the total number of items in the bag.
+//
+// size_type count(const Item& target) const
+// Postcondition: Return value is number of times target is in the bag.
+//
+// NONMEMBER FUNCTIONS for the bag class:
+// bag operator +(const bag& b1, const bag& b2)
+// Postcondition: The bag returned is the union of b1 and b2.
+//
+// VALUE SEMANTICS for the bag class:
+// Assignments and the copy constructor may be used with bag objects.
+//
+// DYNAMIC MEMORY USAGE by the bag:
+// If there is insufficient dynamic memory, then the following functions
+// throw bad_alloc: The constructors, insert, operator +=, operator +, and
+// the assignment operator.
+
+#ifndef BAG6_H
+#define BAG6_H
+#include <cstdlib> // Provides NULL and size_t
+#include "bintree.h" // Provides binary_tree_node and related functions
+
+namespace main_savitch_10
+{
+ template <class Item>
+ class bag
+ {
+ public:
+ // TYPEDEFS
+ typedef std::size_t size_type;
+ typedef Item value_type;
+ // CONSTRUCTORS and DESTRUCTOR
+ bag( );
+ bag(const bag& source);
+ ~bag( );
+ // MODIFICATION functions
+ size_type erase(const Item& target);
+ bool erase_one(const Item& target);
+ void insert(const Item& entry);
+ void operator +=(const bag& addend);
+ void operator =(const bag& source);
+ // CONSTANT functions
+ size_type size( ) const;
+ size_type count(const Item& target) const;
+ private:
+ binary_tree_node<Item> *root_ptr; // Root pointer of binary search tree
+ void insert_all(binary_tree_node<Item>* addroot_ptr);
+ };
+
+ // NONMEMBER functions for the bag<Item> template class
+ template <class Item>
+ bag<Item> operator +(const bag<Item>& b1, const bag<Item>& b2);
+}
+
+#include "bag6.template" // Include the implementation.
+#endif
diff --git a/chapter10/bintree.h b/chapter10/bintree.h new file mode 100644 index 0000000..386fcd4 --- /dev/null +++ b/chapter10/bintree.h @@ -0,0 +1,169 @@ +// FILE: bintree.h (part of the namespace main_savitch_10)
+// PROVIDES: A template class for a node in a binary tree and functions for
+// manipulating binary trees. The template parameter is the type of data in
+// each node.
+//
+// TYPEDEF for the binary_tree_node<Item> template class:
+// Each node of the tree contains a piece of data and pointers to its
+// children. The type of the data (binary_tree_node<Item>::value_type) is
+// the Item type from the template parameter. The type may be any of the C++
+// built-in types (int, char, etc.), or a class with a default constructor,
+// and an assignment operator.
+//
+// CONSTRUCTOR for the binary_tree_node<Item> class:
+// binary_tree_node(
+// const item& init_data = Item( ),
+// binary_tree_node<Item>* init_left = NULL,
+// binary_tree_node<Item>* init_right = NULL
+// )
+// Postcondition: The new node has its data equal to init_data,
+// and it's child pointers equal to init_left and init_right.
+//
+// MEMBER FUNCTIONS for the binary_tree_node<Item> class:
+// const item& data( ) const <----- const version
+// and
+// Item& data( ) <----- non-const version
+// Postcondition: The return value is a reference to the data from
+// this binary_tree_node.
+//
+// const binary_tree_node* left( ) const <----- const version
+// and
+// binary_tree_node* left( ) <----- non-const version
+// and
+// const binary_tree_node* right( ) const <----- const version
+// and
+// binary_tree_node* right( ) <----- non-const version
+// Postcondition: The return value is a pointer to the left or right child
+// (which will be NULL if there is no child).
+//
+// void set_data(const Item& new_data)
+// Postcondition: The binary_tree_node now contains the specified new data.
+//
+// void set_left(binary_tree_node* new_link)
+// and
+// void set_right(binary_tree_node* new_link)
+// Postcondition: The binary_tree_node now contains the specified new link
+// to a child.
+//
+// bool is_leaf( )
+// Postcondition: The return value is true if the node is a leaf;
+// otherwise the return value is false.
+//
+// NON-MEMBER FUNCTIONS to maniplulate binary tree nodes:
+// tempate <class Process, class BTNode>
+// void inorder(Process f, BTNode* node_ptr)
+// Precondition: node_ptr is a pointer to a node in a binary tree (or
+// node_ptr may be NULL to indicate the empty tree).
+// Postcondition: If node_ptr is non-NULL, then the function f has been
+// applied to the contents of *node_ptr and all of its descendants, using
+// an in-order traversal.
+// Note: BTNode may be a binary_tree_node or a const binary tree node.
+// Process is the type of a function f that may be called with a single
+// Item argument (using the Item type from the node).
+//
+// tempate <class Process, class BTNode>
+// void postorder(Process f, BTNode* node_ptr)
+// Same as the in-order function, except with a post-order traversal.
+//
+// tempate <class Process, class BTNode>
+// void preorder(Process f, BTNode* node_ptr)
+// Same as the in-order function, except with a pre-order traversal.
+//
+// template <class Item, class SizeType>
+// void print(const binary_tree_node<Item>* node_ptr, SizeType depth)
+// Precondition: node_ptr is a pointer to a node in a binary tree (or
+// node_ptr may be NULL to indicate the empty tree). If the pointer is
+// not NULL, then depth is the depth of the node pointed to by node_ptr.
+// Postcondition: If node_ptr is non-NULL, then the contents of *node_ptr
+// and all its descendants have been written to cout with the << operator,
+// using a backward in-order traversal. Each node is indented four times
+// its depth.
+//
+// template <class Item>
+// void tree_clear(binary_tree_node<Item>*& root_ptr)
+// Precondition: root_ptr is the root pointer of a binary tree (which may
+// be NULL for the empty tree).
+// Postcondition: All nodes at the root or below have been returned to the
+// heap, and root_ptr has been set to NULL.
+//
+// template <class Item>
+// binary_tree_node<Item>* tree_copy(const binary_tree_node<Item>* root_ptr)
+// Precondition: root_ptr is the root pointer of a binary tree (which may
+// be NULL for the empty tree).
+// Postcondition: A copy of the binary tree has been made, and the return
+// value is a pointer to the root of this copy.
+//
+// template <class Item>
+// size_t tree_size(const binary_tree_node<Item>* node_ptr)
+// Precondition: node_ptr is a pointer to a node in a binary tree (or
+// node_ptr may be NULL to indicate the empty tree).
+// Postcondition: The return value is the number of nodes in the tree.
+
+#ifndef BINTREE_H
+#define BINTREE_H
+#include <cstdlib> // Provides NULL and size_t
+
+namespace main_savitch_10
+{
+
+ template <class Item>
+ class binary_tree_node
+ {
+ public:
+ // TYPEDEF
+ typedef Item value_type;
+ // CONSTRUCTOR
+ binary_tree_node(
+ const Item& init_data = Item( ),
+ binary_tree_node* init_left = NULL,
+ binary_tree_node* init_right = NULL
+ )
+ {
+ data_field = init_data;
+ left_field = init_left;
+ right_field = init_right;
+ }
+ // MODIFICATION MEMBER FUNCTIONS
+ Item& data( ) { return data_field; }
+ binary_tree_node* left( ) { return left_field; }
+ binary_tree_node* right( ) { return right_field; }
+ void set_data(const Item& new_data) { data_field = new_data; }
+ void set_left(binary_tree_node* new_left) { left_field = new_left; }
+ void set_right(binary_tree_node* new_right) { right_field = new_right; }
+ // CONST MEMBER FUNCTIONS
+ const Item& data( ) const { return data_field; }
+ const binary_tree_node* left( ) const { return left_field; }
+ const binary_tree_node* right( ) const { return right_field; }
+ bool is_leaf( ) const
+ { return (left_field == NULL) && (right_field == NULL); }
+ private:
+ Item data_field;
+ binary_tree_node *left_field;
+ binary_tree_node *right_field;
+ };
+
+ // NON-MEMBER FUNCTIONS for the binary_tree_node<Item>:
+ template <class Process, class BTNode>
+ void inorder(Process f, BTNode* node_ptr);
+
+ template <class Process, class BTNode>
+ void preorder(Process f, BTNode* node_ptr);
+
+ template <class Process, class BTNode>
+ void postorder(Process f, BTNode* node_ptr);
+
+ template <class Item, class SizeType>
+ void print(binary_tree_node<Item>* node_ptr, SizeType depth);
+
+ template <class Item>
+ void tree_clear(binary_tree_node<Item>*& root_ptr);
+
+ template <class Item>
+ binary_tree_node<Item>* tree_copy(const binary_tree_node<Item>* root_ptr);
+
+ template <class Item>
+ std::size_t tree_size(const binary_tree_node<Item>* node_ptr);
+}
+
+#include "bintree.template"
+#endif
diff --git a/chapter10/bintree.template b/chapter10/bintree.template new file mode 100644 index 0000000..815aea5 --- /dev/null +++ b/chapter10/bintree.template @@ -0,0 +1,100 @@ +// FILE: bintree.template
+// IMPLEMENTS: The binary_tree node class (see bintree.h for documentation).
+#include <cassert> // Provides assert
+#include <cstdlib> // Provides NULL, std::size_t
+#include <iomanip> // Provides std::setw
+#include <iostream> // Provides std::cout
+
+namespace main_savitch_10
+{
+ template <class Process, class BTNode>
+ void inorder(Process f, BTNode* node_ptr)
+ // Library facilities used: cstdlib
+ {
+ if (node_ptr != NULL)
+ {
+ inorder(f, node_ptr->left( ));
+ f( node_ptr->data( ) );
+ inorder(f, node_ptr->right( ));
+ }
+ }
+
+ template <class Process, class BTNode>
+ void postorder(Process f, BTNode* node_ptr)
+ // Library facilities used: cstdlib
+ {
+ if (node_ptr != NULL)
+ {
+ postorder(f, node_ptr->left( ));
+ postorder(f, node_ptr->right( ));
+ f(node_ptr->data( ));
+ }
+ }
+
+ template <class Process, class BTNode>
+ void preorder(Process f, BTNode* node_ptr)
+ // Library facilities used: cstdlib
+ {
+ if (node_ptr != NULL)
+ {
+ f( node_ptr->data( ) );
+ preorder(f, node_ptr->left( ));
+ preorder(f, node_ptr->right( ));
+ }
+ }
+
+ template <class Item, class SizeType>
+ void print(binary_tree_node<Item>* node_ptr, SizeType depth)
+ // Library facilities used: iomanip, iostream, stdlib
+ {
+ if (node_ptr != NULL)
+ {
+ print(node_ptr->right( ), depth+1);
+ std::cout << std::setw(4*depth) << ""; // Indent 4*depth spaces.
+ std::cout << node_ptr->data( ) << std::endl;
+ print(node_ptr->left( ), depth+1);
+ }
+ }
+
+ template <class Item>
+ void tree_clear(binary_tree_node<Item>*& root_ptr)
+ // Library facilities used: cstdlib
+ {
+ if (root_ptr != NULL)
+ {
+ tree_clear( root_ptr->left( ) );
+ tree_clear( root_ptr->right( ) );
+ delete root_ptr;
+ root_ptr = NULL;
+ }
+ }
+
+ template <class Item>
+ binary_tree_node<Item>* tree_copy(const binary_tree_node<Item>* root_ptr)
+ // Library facilities used: cstdlib
+ {
+ binary_tree_node<Item> *l_ptr;
+ binary_tree_node<Item> *r_ptr;
+
+ if (root_ptr == NULL)
+ return NULL;
+ else
+ {
+ l_ptr = tree_copy( root_ptr->left( ) );
+ r_ptr = tree_copy( root_ptr->right( ) );
+ return
+ new binary_tree_node<Item>( root_ptr->data( ), l_ptr, r_ptr);
+ }
+ }
+
+ template <class Item>
+ size_t tree_size(const binary_tree_node<Item>* node_ptr)
+ // Library facilities used: cstdlib
+ {
+ if (node_ptr == NULL)
+ return 0;
+ else
+ return
+ 1 + tree_size(node_ptr->left( )) + tree_size(node_ptr->right( ));
+ }
+}
diff --git a/chapter10/bt_class.h b/chapter10/bt_class.h new file mode 100644 index 0000000..e35b3a2 --- /dev/null +++ b/chapter10/bt_class.h @@ -0,0 +1,126 @@ +// FILE: bt_class.h
+// For Project 2 in Chapter 10 of "Data Structures and Other Objects Using C++"
+// TEMPLATE CLASS PROVIDED: binary_tree<Item> (a binary tree where each node has
+// an item) The template parameter, Item, is the data type of the items in the
+// tree's nodes. It may be any of the C++ built-in types (int, char, etc.),
+// or a class with a default constructor, a copy constructor and an assignment
+// operator.
+//
+// NOTE: Each non-empty tree always has a "current node." The location of
+// the current node is controlled by three member functions: shift_up,
+// shift_to_root, shift_left, and shift_right.
+//
+// CONSTRUCTOR for the binary_tree<Item> template class:
+// binary_tree( )
+// Postcondition: The binary tree has been initialized as an empty tree
+// (with no nodes).
+//
+// MODIFICATION MEMBER FUNCTIONS for the binary_tree<Item> template class:
+// void create_first_node(const Item& entry)
+// Precondition: size( ) is zero.
+// Postcondition: The tree now has one node (a root node), containing the
+// specified entry. This new root node is the "current node."
+//
+// void shift_to_root( )
+// Precondition: size( ) > 0.
+// Postcondition: The "current node" is now the root of the tree.
+//
+// void shift_up( )
+// Precondition: has_parent( ) returns true.
+// Postcondition: The "current node" has been shifted up to the parent of
+// the old current node.
+//
+// void shift_left( )
+// Precondition: has_left_child( ) returns true.
+// Postcondition: The "current node" been shifted down to the left child
+// of the original current node.
+//
+// void shift_right( )
+// Precondition: has_right_child( ) returns true.
+// Postcondition: The "current node" been shifted down to the right child
+// of the original current node.
+//
+// void change(const Item& new_entry)
+// Precondition: size( ) > 0.
+// Postcondition: The data at the "current node" has been changed to the
+// new entry.
+//
+// void add_left(const Item& entry)
+// Precondition: size( ) > 0, and has_left_child( ) returns false.
+// Postcondition: A left child has been added to the "current node,"
+// with the given entry.
+//
+// void add_right(const Item& entry)
+// Precondition: size( ) > 0, and has_right_child( ) returns false.
+// Postcondition: A right child has been added to the "current node,"
+// with the given entry.
+//
+// CONSTANT MEMBER FUNCTIONS for the binary_tree<Item> template class:
+// size_t size( ) const
+// Postcondition: The return value is the number of nodes in the tree.
+//
+// Item retrieve( ) const
+// Precondition: size( ) > 0.
+// Postcondition: The return value is the data from the "current node."
+//
+// bool has_parent( ) const
+// Postcondition: Returns true if size( ) > 0, and the "current node"
+// has a parent.
+//
+// bool has_left_child( ) const
+// Postcondition: Returns true if size( ) > 0, and the "current node"
+// has a left child.
+//
+// bool has_right_child( ) const
+// Postcondition: Returns true if size( ) > 0, and the "current node"
+// has a right child.
+//
+// VALUE SEMANTICS for the binary_tree<Item> template class:
+// Assignments and the copy constructor may be used with binary_tree objects.
+//
+// DYNAMIC MEMORY USAGE by the binary_tree<Item> template class:
+// If there is insufficient dynamic memory, then the following functions
+// throw bad_alloc:
+// create_first_node, add_left, add_right, the copy constructor, and the
+// assignment operator.
+
+#ifndef BT_CLASS_H
+#define BT_CLASS_H
+#include <cstdlib> // Provides size_t
+#include "bintree.h" // Provides binary_tree_node<Item> template class
+
+namespace main_savitch_chapter10
+{
+ template <class Item>
+ class binary_tree
+ {
+ public:
+ // CONSTRUCTORS and DESTRUCTOR
+ binary_tree( );
+ binary_tree(const binary_tree& source);
+ ~binary_tree( );
+ // MODIFICATION MEMBER FUNCTIONS
+ void create_first_node(const Item& entry);
+ void shift_to_root( );
+ void shift_up( );
+ void shift_left( );
+ void shift_right( );
+ void change(const Item& new_entry);
+ void add_left(const Item& entry);
+ void add_right(const Item& entry);
+ // CONSTANT MEMBER FUNCTIONS
+ std::size_t size( ) const;
+ Item retrieve( ) const;
+ bool has_parent( ) const;
+ bool has_left_child( ) const;
+ bool has_right_child( ) const;
+ private:
+ // Private member variables to be specified by the student.
+ // My own implementation has a root pointer and a pointer to
+ // the "current" node, plus a member variable to keep track of
+ // the number of nodes in this tree.
+ };
+}
+
+#include "bt_class.template" // To be written by the student
+#endif
diff --git a/chapter10/useful.cxx b/chapter10/useful.cxx new file mode 100644 index 0000000..694016b --- /dev/null +++ b/chapter10/useful.cxx @@ -0,0 +1,80 @@ +// FILE: useful.cxx
+// IMPLEMENTS: A toolkit of functions (See useful.h for documentation.)
+
+#include <cassert> // Provides assert
+#include <cctype> // Provides toupper
+#include <cstdlib> // Provides rand, RAND_MAX
+#include <iostream.h> // Provides cout, cin, get
+#include "useful.h"
+
+void display(double x)
+// Library facilities used: iostream.h, stdlib.h
+{
+ const char STAR = '*';
+ const char BLANK = ' ';
+ const char VERTICAL_BAR = '|';
+ const int LIMIT = 39;
+ int i;
+
+ if (x < -LIMIT)
+ x = -LIMIT;
+ else if (x > LIMIT)
+ x = LIMIT;
+
+ for (i = -LIMIT; i < 0; i++)
+ {
+ if (i >= x)
+ cout << STAR;
+ else
+ cout << BLANK;
+ }
+ cout << VERTICAL_BAR;
+ for (i = 1; i <= LIMIT; i++)
+ {
+ if (i <= x)
+ cout << STAR;
+ else
+ cout << BLANK;
+ }
+ cout << endl;
+}
+
+double random_fraction( )
+// Library facilities used: stdlib.h
+{
+ return rand( ) / double(RAND_MAX);
+}
+
+double random_real(double low, double high)
+// Library facilities used: assert.h
+{
+ assert(low <= high);
+ return low + random_fraction( ) * (high - low);
+}
+
+void eat_line( )
+// Library facilities used: iostream.h
+//
+{
+ char next;
+
+ do
+ cin.get(next);
+ while (next != '\n');
+}
+
+bool inquire(const char query[ ])
+// Library facilities used: ctype.h, iostream.h
+{
+ char answer;
+ do
+ {
+ cout << query << " [Yes or No]" << endl;
+ cin >> answer;
+ answer = toupper(answer);
+ eat_line( );
+ }
+ while ((answer != 'Y') && (answer != 'N'));
+ return (answer == 'Y');
+}
+
diff --git a/chapter10/useful.h b/chapter10/useful.h new file mode 100644 index 0000000..25dd03e --- /dev/null +++ b/chapter10/useful.h @@ -0,0 +1,46 @@ +// FILE: useful.h
+// PROVIDES: A toolkit of useful functions for random numbers and displays.
+// Note that these are in the global namespace.
+//
+// FUNCTIONS in the toolkit:
+// double random_fraction( )
+// Postcondition: The return value is a random real number in the closed
+// interval [0..1] (including the endpoints).
+//
+// double random_real(double low, double high)
+// Precondition: low <= high.
+// Postcondition: The return value is a random real number in the closed
+// interval [low..high] (including the endpoints).
+//
+// void display(double x)
+// Postcondition: The function has written one line of output to the
+// standard ouput, with a vertical bar in the middle. If x is positive,
+// then approximately x stars are printed to the right of the vertical
+// bar. If x is negative, then approximately -x stars are printed to the
+// left of the vertical bar. If the absolute value of x is more than
+// 39, then only 39 stars are printed.
+// Examples:
+// display(8) prints: |********
+// display(-4) prints: ****|
+//
+// void eat_line( )
+// Postcondition: Up to next newline has been read and discarded from cin.
+//
+// bool inquire(const char query[ ])
+// Precondition: query is a null-terminated string of characters.
+// Postcondition: query has been printed, and a one-line response read
+// from the user. The function returns true if the user's response begins
+// with 'Y' or 'y', and returns false if the user's response begins with
+// 'N' or 'n'. (If the response begins with some other letter, then the
+// query is repeated.)
+
+#ifndef USEFUL_H // Prevent duplicate definition
+#define USEFUL_H
+
+ double random_fraction( );
+ double random_real(double low, double high);
+ void display(double x);
+ void eat_line( );
+ bool inquire(const char query[ ]);
+
+#endif
|