I've got a program to do for a class I'm taking. I've got most the code written but I can't get the two classes to play together like I want them to.

Here is the relavent part of the assignment:

A concordance is an alphabetical listing of all words in a text
with a list associated with each word of the line numbers in which the
word appears

Design and implement two C++ classes for linked lists (see below).

Design, code and test a C++ program using the linked lists that
reads a text file (using file redirection) and generates a concordance of
all the words from that text.

You will need a linked list of strings and linked list of numbers, Each
node of the string list must point to a list of numbers.

One class, wordlist, uses the other class numlist to keep a list of line numbers in which a certain word was found. When I test both classes alone, they work as I think they should, but when I try to use numlist called from wordlist, it only remembers the first line number inserted when you put the same word in.

wordlist.h

#ifndef linkdlst_h 
#include <iostream>
#include <string>
/* HUGELY IMPORTANT NOTE:
 *
 * This class is dependant upon the other node class!  It will fail without it! */
#include "numlist.h"


using namespace std;

class concordance
  {
	private:
		
	  struct node
		{
		  string data;
			numlist line_nums;
			node *next;
		};
		node *list_head;
		

	
	// Methods
	  bool is_before(string list_data, string data);
		bool is_same(string list_data, string data);
		bool is_after(string list_data, string data);
		//Note: is_first is implied--it's a one line thing
		string tolowercase(string str);
		
	public:
		concordance();
		~concordance();
		
		void append(string data, int n);
		void insert(string data, int n);
		void print();
	};

#define linkdlst_h
#endif

Exert from wordlist.cpp (I didn't include the private functions such as touppercase and is_same--they work.)

concordance::concordance()
  {
	list_head = NULL;
	}
	
concordance::~concordance()
  { //The destructor may have to do something here.
	node *previous;
	node *current;
	previous = current = list_head;
	while (current != NULL) //Delete each item in the list.
	  {
		current = previous -> next;
 		previous -> line_nums.~numlist();
		delete previous;
		previous = current;
		}
	previous = current = list_head = NULL;
	}

void concordance::insert(string data, int n)
  {
	node* current = list_head;
	node* previous = list_head;
	node* newnode = NULL;
	bool done = false; // After the loop has executed, exit it.
	
	// Create a node to insert the data into
	newnode = new(node);
	newnode -> data = data;
	newnode -> line_nums.append(n);
			
	// Build the list by inserting data in an organized manner.
	if (list_head != NULL)
	  {
		while (done == false)
		  {
			if (is_before(current -> data, data))
				{ //Insert into the list
				newnode -> next = previous -> next;
				previous -> next= newnode;
				done = true;
				}
			else if (is_same(current -> data, data))
			  {
// cout << "is_same ";				
				//Append line number to line number list
 				newnode -> line_nums.append(n);
				done = true;
				}
			else
				{ //if !is_before and !is_same, it must be is_after.
		 		if (current -> next == NULL)
					{
				  //The end of list has been reached.
					//Insert at the end
					newnode -> next = NULL;
					current -> next = newnode;
					done = true;
					}
				else
				  {
					previous = current;
					current = current -> next;
					done = false;
					}
				}
			}
		}
		else
	  {
		newnode -> next = NULL;
		list_head = newnode;
		}
	}
void concordance::print()
  {
	node *current;
  current = list_head;
	while (current != NULL)
	  {
	  cout << current -> data << " <- data | position -> ";
  	current -> line_nums.print();
		cout << endl;
	  current = current -> next;
	  }
	}

numlist.h

/* Source: Program 0, Assignment 7. */
#ifndef numlist_h 
#include <iostream>

using namespace std;

class numlist
  {
	private:
	  struct node
		{
		  int data;
			node *next;
		};
		node *list;
	
	public:
    typedef node *node_ptr;
		numlist();
		~numlist();
		bool defined;
		
		void append(int n);
		void print();

	};
		
#define numlist_h
#endif

numlist.cpp

#include "numlist.h"

numlist::numlist()
  {
	list = NULL;
  }

numlist::~numlist()
  { //The destructor may have to do something here.
	node *previous;
	node *current;
	previous = current = list;
	while (current != NULL) //Delete each item in the list.
	  {
		current = previous -> next;
		delete previous;
		previous = current;
		}
	previous = current = list = NULL;
	}


void numlist::append(int str)
  {
	node *current;
	node *newnode;
	current = newnode = NULL;

  //Create a new node to put the data in.
	newnode = new(node);
	newnode -> data = str;
	newnode -> next = NULL;

cout << " List Head: " << list << " Current: " << current << endl;		
	//Decide where to put it.	
	if (current == NULL) //Then this is an empty list.
	  {
		list = newnode;
		}
	else //Find the end of the list
	  {
		while (current -> next != NULL)
		  {
			current = current -> next;
			}
cout << " List Head: " << list << " Current: " << current << endl;		
		current -> next = newnode;
		}
//		print();
  }
		

void numlist::print()
  {
	node *current;
  current = list;
	while (current != NULL)
	  {
	  cout << current -> data << " ";
	  current = current -> next;
	  }
	}

My test program for wordlist.cpp simply asks for input (cin) and uses the insert procedure to add data to the list.

The test program for numlist.cpp just adds a bunch of data and prints out the list.

Thanks for any suggestions you have. I'm out of ideas here.

Attachments
Assignment 2, Concordance


Using two linked list classes, read in words from the list to build an alphabetical listing of 
words and line numbers.

Class implements list of words:
[Data | Pointer to line numbers | Pointer to next node]

[Pointer to line numbers] -> [Line number | Next node]

Ends of words are:
, . ; : ! ? - )	End_Of_Line Space

( is not a word or letter.  (Therefore, it can be ignored.)

Notes:
This implementation won't recognize terms.  The best way to do this would be to implement a 
look-up table of common terms, but this is outside of the scope of the assignment.

Word terminators will not appear in the concordance's listing.

Lines
-----
Lines will be counted by looking for end of line characters.  This is ASCII 10_10 or 0A_16.

Command line redirection presents a huge world of problems.

Lists
-----
Two classes will contain a linked list and their assorted methods.

Psuedocode algorithms and ideas:
The data list will be built sorted.  A second list will be built containing the original file in
its order.  This could probably be simplified in this case by executing a shell command (TYPE on
Windows, cat on Linux.) to print out the original file, but the assignment doesn't allow for it.

Alternate idea:
Depending on the amount of data used, traversing the list can take a long time.  By implementing
index pointers (An array of pointers?), the amount of data to traverse is minimized.  If lucky or
bored, this may be implemented.


Master List
-----------

There are four basic functions invoked in building the master list:
is_first
	This simply tests the head pointer for NULL
	If true, append to master list
	Add line numbers to appropriate list
	
is_before
  insert the data before the node
	Add line numbers to appropriate list

is_same
  Add line number to appropriate list

is_after
  If not the last node (list -> next != NULL) then go to next item in list and test again.
	If it is the last node, append to end of master list. 
	

Definition:  full node
	Data is added into the node, and the line_numbers pointer refers to a list of line numbers.
	
Methods:
Append
	Take a full node and update the list -> next pointer to the address referenced by the
	pointer to the new node.
	
Create
	Construct a list using the constructor.
	
Insert
	Only happens if (is_before == true)
	Given a full node:
	Update the <next> field of the full node to point to the <next> field of the list item
	before the insertion point.
	Update the <next> field of the list item before the insertion point to point to the address
	of the full node.
	
Delete
	This is the destructor.  Traverse the list freeing the memory referenced by
	elements of the list.


Numbers list
------------

There are three functions required in this list:
  Create -- constructor
	Append -- add one item to the list
	Delete -- destructor

I was not able to get this to work properly before the due date. For some reason the program sets the pointer to the linked list of numbers to null if I call the insert procedure with anything other than what I had called it before.

This works:
insert("Hey", 3)
insert("Hey", 4)

Output:
Hey 3 4

This doesn't:
insert("Hey", 3)
insert("Hi", 4)

Hey [null]
Hi 4

This article has been dead for over six months. Start a new discussion instead.