Please send questions to
st10@humboldt.edu .
/*-----------------------------------------------------------
a string_list2 is a class:
string_list2
...representing a list with:
a size,
the strings it currently contains
template for a function involving a string_list2:
ret_type process_string_list2(string_list2 a_string_list2)
{
return ...a_string_list2.get_length()...
...a_string_list2.get_element(i)...
}
-------------------------------------------------------------*/
#include "string_list2.h"
using namespace std;
// constructor
string_list2::string_list2()
{
first = NULL;
curr_size = 0;
}
// destructor
string_list2::~string_list2()
{
string_node* next_node;
string_node* temp;
next_node = first;
// walk through the list, deallocating each node
while (next_node != NULL)
{
temp = next_node;
next_node = next_node->get_next();
delete temp;
temp = NULL;
}
}
// copy constructor
string_list2::string_list2(const string_list2& a_string_list2)
{
string_node* prev_old;
string_node* next_old;
string_node* prev_new;
string_node* next_new;
// INSIDE this class -- can access private data fields;
curr_size = a_string_list2.curr_size;
if (curr_size == 0)
{
first = NULL;
}
else if (curr_size == 1)
{
first = new string_node( (a_string_list2.first)->get_value() );
}
else
{
first = new string_node( (a_string_list2.first)->get_value() );
prev_old = a_string_list2.first;
next_old = (a_string_list2.first)->get_next();
prev_new = first;
while (next_old != NULL)
{
next_new = new string_node( next_old->get_value() );
prev_new->set_next(next_new);
prev_new = next_new;
prev_old = next_old;
next_old = next_old->get_next();
}
}
}
// selectors
int string_list2::get_length() const
{
return curr_size;
}
// signature: string_list2::get_element: int -> string
// purpose: expects the "index" (starting with 0, like an
// array) of the list element desired, and produces
// the string at that position in this string_list2
// examples: for:
// string_list2 greetings;
// greetings.add("hi");
// greetings.add("hello");
// greetings.add("howdy");
//
// greetings.get_element(0) == "hi"
// greetings.get_element(2) == "howdy"
string string_list2::get_element(int index) const
{
string element_value;
// if had time, we would throw an EXCEPTION if
// someone tried to access a "nonexistent" element --
// as a cheesy first step, we'll just return an empty string
// if they try that
if (index >= curr_size)
{
element_value = "";
}
else
{
string_node* curr_node = first;
// take a number of "steps" through the list
// equal to the desired index so that curr_node
// points to the desired list element
for (int i=0; i<index; i++)
{
curr_node = curr_node->get_next();
}
// now curr_node should point to the index'th element
element_value = curr_node->get_value();
}
return element_value;
}
// modifiers
// signature: string_list2::add: string -> void
// purpose: expects a string, and produces nothing, but
// has the side-effect of adding the given string
// to the end of the list (making it its last element)
// examples: after:
// string_list2 greetings;
// greetings.add("hi");
//
// now:
// greetings.get_size() == 1
// greetings.get_element(0) == "hi"
//
// and then after:
// greetings.add("hello");
//
// now:
// greetings.get_size() == 2
// greetings.get_element(1) == "hello"
void string_list2::add(string new_string)
{
string_node* curr_node;
// is this the first node in the list?
if (first == NULL)
{
first = new string_node(new_string);
}
else
{
curr_node = first;
// "walk" to end of the list
while (curr_node->get_next() != NULL)
{
curr_node = curr_node->get_next();
}
// now curr_node points to the last node -- add
// the new element after this node
curr_node->set_next( new string_node(new_string) );
}
curr_size++;
}
// signature: string_list2::remove: string -> bool
// purpose: expects a string, and tries to remove its
// first instance from the calling string_list2,
// producing true if it finds it and removes it,
// and producing false if the string is not in the string_list2
// examples: after:
// string_list2 greetings;
// greetings.add("hi");
// greetings.add("howdy");
// greetings.add("hi");
// greetings.add("hello");
//
// greetings.remove("hi") == true
// and after:
// greetings.get_size() == 3
// greetings.get_element(0) == "howdy"
// (and greetings contains "howdy", "hi", "hello")
//
// greetings.remove("bonjour") == false
// greetings.get_size() == 3
// greetings.get_element(0) == "howdy"
// (and greetings contains "howdy", "hi", "hello")
bool string_list2::remove(string a_string)
{
bool found = false;
string_node* prev;
string_node* curr;
prev = NULL;
curr = first;
while ((!found) && (curr != NULL))
{
if (curr->get_value() == a_string)
{
found = true;
}
else
{
prev = curr;
curr = curr->get_next();
}
}
// if you FOUND it -- REMOVE it;
if (found)
{
// special case: element is the FIRST in the list
if (prev == NULL)
{
first = curr->get_next();
}
// otherwise, it is NOT the first in the list
else
{
prev->set_next( curr->get_next() );
}
// either way, now safe to deallocate what curr points to,
// and to adjust the curr_size accordingly
delete curr;
curr_size--;
return true; // remove succeeded
}
else
{
return false; // removal did not succeed -- string not in list
}
}
// overloaded operator =
string_list2& string_list2::operator =(const string_list2& right_side)
{
string_node* prev_node;
string_node* next_node;
string_node* temp;
string_node* right_side_next;
// only go to the trouble of copying if this isn't a
// a self-assignment
if (this != &right_side)
{
// deallocate the memory for current version of calling list
next_node = first;
// walk through the list, deallocating each node
while (next_node != NULL)
{
temp = next_node;
next_node = next_node->get_next();
delete temp;
temp = NULL;
}
curr_size = right_side.curr_size;
if (right_side.first == NULL)
{
first = NULL;
}
else
{
first = new string_node( (right_side.first)->get_value() );
right_side_next = (right_side.first)->get_next();
prev_node = first;
while (right_side_next != NULL)
{
next_node = new string_node( right_side_next->get_value() );
prev_node->set_next( next_node );
right_side_next = right_side_next->get_next();
prev_node = next_node;
}
}
}
return *this;
}