Phonebook Search
Download: phonebook.tar.gz
Author: paulie
License: n/a
Description:
- Written in C++ for numerous environments
- Creates a tree of phonebook entries
- Object oriented design that allows easy lookup, removal, and display features
// CSCI 2270
// Assignment 5 :: The PhoneBook by Paul Johnson
// This probably won't compile and is for viewing purposes only
// Refer to actual download for full program

#include <iostream>
#include <istream>
#include <iomanip>
#include <fstream>
#include <string>

char printMenu();
using namespace std;
PhoneBook book;

int main() 
{
    int count = 0;
    char choice;
    string file, search, areacode, phonenumber, copy;
    PhoneBookNode* found = 0;
    PhoneBookEntry info;

    cout << "\nAssignment 5: The PhoneBook by Paul Johnson\n" << endl;
    choice = printMenu();
    while (choice != 'q') 
    {
        if (choice == 'r') 
        {
            cout << "Enter the name of a phonebook file: ";
	    cin >> file;
	    ifstream ifs;
	
            if (book.root != NULL)
	    {
	        delete book.root;
	        book.root = NULL;
	    }
	    
            ifs.open(file.c_str());

	    while (ifs.peek()!=EOF)
	    {
	        PhoneBookEntry newEntry;
	        ifs >> newEntry;
	        ifs.get();
	        book.createNodes(newEntry,book.root);
                cout << "Node Created - " << count << endl;
		count++;
	    }
	    ifs.close();
        }

        if (choice == 'p') 
        {
            book.root->printTree();
        }

        if (choice == 'l') 
        {
            cout << "Enter the Area Code in the format xxx: ";
            cin >> areacode;
            cout << "Enter the Phone# in the format xxx-xxxx: ";
            cin >> phonenumber;

            copy = "(";
            copy = copy + areacode;
            copy = copy + ")";
            search = copy + phonenumber;

	    cout << "\nYou searched for the number " << search << "." << endl;	
            found = book.findNumber(search);
	
            if (found == NULL)
	    {
                cout << "Sorry, your number was not found." << endl;
	    }
	    else
            {
	        cout << *found << endl;
            }
        }

        if (choice == 'd') 
        {  
            book.deleteNode(found);
	    cout << search << " was deleted from the tree." << endl;
        }

        if (choice == 's') 
        { 
            book.root->sidewaysTree(4);
        }

        choice = printMenu();
    }
}

char printMenu() 
{
    char choice = ' ';

    cout << "	'r': read a phone book file and build the search tree" << endl;
    cout << "	'p': print the phone book in the order of phone numbers" << endl;
    cout << "	'l': look up a phone number" << endl;
    cout << "	'd': delete the most recently looked up number from the tree" << endl;
    cout << "	's': print the first four levels of the tree 'sideways'" << endl;
    cout << "	'q': quit" << endl; 
    cin >> choice;
 
    return (choice);
}

class PhoneBook
{
    friend class PhoneBookEntry;
    friend class PhoneBookNode;

  public:
      // constructor
    PhoneBook();
      // creates nodes that build the tree based on the inputted file
    void createNodes(PhoneBookEntry &entry, PhoneBookNode* root);
      // deletes the node containing the current phone# looked up
    void deleteNode(PhoneBookNode* deleted);
      // searches the tree for the given phone#
    PhoneBookNode* findNumber(std::string number); 

    PhoneBookNode* root;

};

PhoneBook::PhoneBook()
{
    root = NULL;
}

void PhoneBook::createNodes(PhoneBookEntry &entry,PhoneBookNode* current)
{
    if (root == NULL)
    {
        root = new PhoneBookNode(entry);
    }

    else
    {
        if (entry < current->entry)
        {
            if (current->left == NULL)
	    {
                current->left = new PhoneBookNode(entry);
	    }
        
            else
            {
	        current = current->left;
	        createNodes(entry, current);
	    }
        }
        else 
        {
            if (current->right == NULL)
	    {
                current->right = new PhoneBookNode(entry);
	    }
            else
	    {
                current = current->right;
	        createNodes(entry, current);
            }
	}
    }
}

void PhoneBook::deleteNode(PhoneBookNode* deleted)
{
    PhoneBookNode* current, *previous;
    current = deleted;

    if (current->right != NULL)
    {
        current = current->right;
        previous = current;

        while (current->left != NULL)
        {
   	    previous = current;
	    current = current->left;
        }

        previous->left = current->right;
    }
    else 
    {
        if (current->left != NULL)
        {
            current = current->left;
            deleted->left = current->left;
            deleted->right = current->right;
        }

  	else
        {
            current = root;
            while (current->left != deleted && current->right != deleted)
	    {
	        if (current->entry < deleted->entry)
	        {
		    current = current->right;
	        }

		else
		{
	            current = current->left;
		}
	    }
 
            if (current->right == deleted)
	    {
	        current->right = NULL;
	    }

            if (current->left == deleted)
	    {
		current->left = NULL;
	    }
        }

        delete deleted;
        return;
    }
  
    deleted->entry = current->entry; 
    current->right = NULL;
    current->left = NULL;
    delete current;
}

PhoneBookNode* PhoneBook::findNumber(std::string phonenumber)
{
    PhoneBookNode* current;
    current = root;
  
    while (current != NULL)
    {
        if (current->entry.phonenumber == phonenumber)
	{
    	    return current;
	}

        if (current->entry.phonenumber > phonenumber)
	{
	    current = current->left;
	}
        else
	{
	    current = current->right;
        }
    }
    return NULL;
}

class PhoneBookEntry
{
    friend class PhoneBook;
    friend class PhoneBookNode;

    friend std::istream& operator>>(std::istream &in, PhoneBookEntry &entry);
    friend std::ostream& operator<<(std::ostream &out, PhoneBookEntry &e); 
    friend bool operator<(PhoneBookEntry &entry1, PhoneBookEntry &entry2);
    
  public:
    PhoneBookEntry(){}

  private:
    std::string theRest;
    std::string phonenumber;
};

istream& operator>>(istream &in, PhoneBookEntry &e)
{
    e.phonenumber = '(';
    for(int i = 0; i<89; i++)
    {
	e.theRest += in.get();
    }

    in.get();

    for(int i = 0; i<4; i++)
    {
	e.phonenumber += in.get();
    }

    in.get();

    for(int i = 0; i<8; i++)
    {
	e.phonenumber += in.get();
    }

    return in;
}

ostream& operator<<(ostream &out, PhoneBookEntry &e)
{
   out << e.theRest << " " << e.phonenumber << " "<< endl;
   return out;
}

bool operator<(PhoneBookEntry &e1, PhoneBookEntry &e2)
{
    return e1.phonenumber < e2.phonenumber;
}

class PhoneBookNode
{
    friend class PhoneBookEntry;
    friend class PhoneBook;

    friend std::ostream& operator<<(std::ostream& out, PhoneBookNode &a1);
    friend bool operator==(PhoneBookEntry &e1, PhoneBookEntry &e2);

  public:

    PhoneBookNode(const PhoneBookEntry &entry);
    PhoneBookNode():left(NULL),right(NULL){}
    ~PhoneBookNode();
      // prints the sorted tree of phone#'s to the terminal
    void printTree();
      // prints the first four levels of the phone#'s of the tree to the terminal
    void sidewaysTree(int depth);

  private:
    PhoneBookEntry entry;
    PhoneBookNode *left;
    PhoneBookNode *right;
};

PhoneBookNode::PhoneBookNode(const PhoneBookEntry &e)
{
    entry = e;
    left = NULL;
    right = NULL;
}

PhoneBookNode::~PhoneBookNode()
{
    delete left;
    delete right;
}

void PhoneBookNode::printTree()
{
    if (left != NULL)
    {
        left->printTree();
    }

    cout << entry.theRest << entry.phonenumber << endl;

    if (right != NULL)
    {
	right->printTree();
    }
}

void PhoneBookNode::sidewaysTree(int depth)
{
    if (depth <= 0)
    {
	return;
    }

    if (right != NULL)
    {
        right->sidewaysTree(depth-1);
    }

    cout << setw(4*(4 - depth)) << ' ' << entry.phonenumber << endl;

    if (left != NULL)
    {
	left->sidewaysTree(depth-1);
    }
}

ostream& operator <<(ostream& out, PhoneBookNode &a1)
{
    out << a1.entry;
    return out;
}

bool operator ==(PhoneBookEntry &e1, PhoneBookEntry &e2)
{
    return (e1 == e2);
}