今回の課題は二分木を使ったプログラムです。
ussyms.txt の中には会社のコードとその会社の名前が入っています。実際この中には10,000個のデータが入ってます。
そしてこの情報は連結リストの中に入ります。
例:
BDR; Blonder Tongue Laboratories, Inc.
KAZ; BMB Munai, Inc.
BMI:A; BMI:A
BNP; BNP RESIDENTIAL PPTYS INC
BTJ; Bolt Technology Corporation
BOO:A; BOO:A
BOO:P; BOO:P
WEL; Boots and Coots International Well Control, Inc.
AIG; American International Group, Inc.
そしてもうひとつのテキスト、stocks200901.txt の中にはその会社のStock情報が入っています。
そしてこの情報は二分木の中へ
例:
20090126,NTAP,15.3,15.91,14.7,14.85,106797
20090127,KSS,38.28,39,36.99,37.52,72699
20090112,MAT,15.29,15.43,15.08,15.19,34856
20090113,PEP,51.39,52.46,51.2,52.23,92957
20090114,AIG,1.54,1.55,1.49,1.49,309956
左から date, stock_code,opening_price,high_price,low_price,closing_price,volume_of_shares_exchanged となっています。
このプログラムはユーザーに会社のコードと日付を入力させ。その情報を連結リストと二分木から取り出して情報を書き出すというものです。
アウトプットサンプル:
American International Group, Inc.
(AIG)
March 24, 2009
Opening price: $1.42
Daily high price: $1.54
Daily low price: $1.32
Closing price: $1.39
Shares exchanged: 2269576
Daily change: -2.11% // (closing cost - opening cost) ÷ opening cost * 100
さて僕のプログラムなのですが、データを連結リストと二分木に入れたことはできたと思います。しかしその二分木に入ったデータを呼び出すことができません。自分なりにがんばってみたのですが、自分でも何をやってるのか混乱してしまいます。
どうしたらいいのかアイデアを分けていただけたらと思います。
よろしくお願いします。
Driver.cpp:
#include<string.h>
#include<iostream>
#include<fstream>
#include<cstdlib>
using namespace std;
#include"StockInfo.h"
#include"Code.h"
#include"OrderLinkedList.h"
#include"BinTreeType.h"
#include"StringTokenizer.h"
string getcode();
string getdate();
void getCInfo(OrderLinkedList<Code>& OLL);
void getSInfo(BinTreeType<StockInfo>& BTTSI);
int main()
{
OrderLinkedList<Code> OLLCO;
BinTreeType<StockInfo> BTTSI;
Code CO;
StockInfo SI;
getCInfo(OLLCO);
getSInfo(BTTSI);
string code = getcode();
string date = getdate();
CO.setcode(code);
SI.setcode(code);
SI.setdate(date);
BTTSI.searchNode(SI);
// cout << SI.getcode();
cout << SI << endl;
// BTTSI.displayInOrder();
SI.write(OLLCO, CO);
cout << "END" << endl;
return 0;
}
// getting data from ussyms.txt
// and putting into Code
void getCInfo(OrderLinkedList<Code>& OLLCO)
{
Code CO;
string Ccode, name;
ifstream inFile1;
inFile1.open("ussyms.txt");
getline(inFile1, Ccode, ';');
CO.setcode(Ccode);
getline(inFile1, name);
CO.setname(name);
OLLCO.insertNode(CO);
while(!inFile1.eof())
{
getline(inFile1, Ccode, ';');
CO.setcode(Ccode);
getline(inFile1, name);
CO.setname(name);
OLLCO.insertNode(CO);
}
}
// getting data from stocks200901.txt"
// and putting into StockInfo
void getSInfo(BinTreeType<StockInfo>& BTTSI)
{
StockInfo SI;
string date, volume;
double hi, low, close, open;
string Scode, line;
ifstream inFile2;
inFile2.open("stocks200901.txt");
getline(inFile2, line);
StringTokenizer ST(line);
date = ST.getIntToken();
Scode = ST.getStringToken();
open = ST.getDoubleToken();
hi = ST.getDoubleToken();
low = ST.getDoubleToken();
close = ST.getDoubleToken();
volume = ST.getIntToken();
SI.setinfo(date, Scode, open, hi, low, close, volume);
BTTSI.insertNode(SI);
while(!inFile2.eof())
{
ST.reset();
getline(inFile2, line);
ST.setLine(line);
date = ST.getIntToken();
Scode = ST.getStringToken();
open = ST.getDoubleToken();
hi = ST.getDoubleToken();
low = ST.getDoubleToken();
close = ST.getDoubleToken();
volume = ST.getIntToken();
SI.setinfo(date, Scode, open, hi, low, close, volume);
BTTSI.insertNode(SI);
}
}
// for user to input code
string getcode()
{
string code;
cout << "What is the code?: ";
cin >> code;
return code;
}
// for user to input date
string getdate()
{
string date;
while(date.length() != 8)
{
cout << "What is the date?(yyyymmdd): ";
cin >> date;
}
return date;
}
Code.h:
#pragma once
#include"OrderLinkedList.h"
class Code
{
private:
OrderLinkedList<string> OLL;
string cocode; // company code
string coname; // company name
public:
Code();
//Overload operators
bool operator<(Code oper);
bool operator==(Code oper);
// set functions
void setcode(string cocode);
void setname(string coname);
// get name
string getname();
};
// default constructor
Code::Code()
{
cocode = " ";
coname = " ";
}
void Code::setcode(string code)
{
cocode = code;
}
void Code::setname(string name)
{
coname = name;
}
bool Code::operator<(Code oper)
{
if(cocode < oper.cocode)
return true;
return false;
}
bool Code::operator==(Code oper)
{
if(cocode == oper.cocode)
return true;
return false;
}
string Code::getname()
{
return coname;
}
#pragma once
#include"OrderLinkedList.h"
#include"Code.h"
class StockInfo
{
private:
string date;
string stcode; // string code
double opprice; // open price
double hiprice; // high price
double clprice; // close price
double loprice; // low price
string volume;
public:
StockInfo();
StockInfo(string filename);
void setinfo(string sdate, string sstcode,
double sopprice, double shiprice,
double sloprice, double sclprice,
string svolume);
bool operator<(StockInfo oper);
bool operator==(StockInfo oper);
void setdate(string sdate);
void setcode(string scode);
string getcode();
string line3();
string convertmonth();
void write(OrderLinkedList<Code> OLLCO, Code CO);
friend ostream& operator<< (ostream &strm, StockInfo &theObj);
};
// default constructor
StockInfo::StockInfo()
{
date = " ";
stcode = " ";
opprice = 0.0;
clprice = 0.0;
loprice = 0.0;
hiprice = 0.0;
volume = " ";
}
// constructor
void StockInfo::setinfo(string sdate, string sstcode,
double sopprice, double shiprice,
double sloprice, double sclprice,
string svolume)
{
date = sdate;
stcode = sstcode;
opprice = sopprice;
hiprice = shiprice;
loprice = sloprice;
clprice = sclprice;
volume = svolume;
}
bool StockInfo::operator<(StockInfo oper)
{
bool flag = false;
if(stcode < oper.stcode)
{
flag = true;
}
else if(stcode == oper.stcode && date < oper.date)
{
flag = true;
}
return flag;
}
bool StockInfo::operator==(StockInfo oper)
{
if(stcode == oper.stcode && date == oper.date)
return true;
return false;
}
string StockInfo::convertmonth()
{
string cut, Namonth;
if(date.at(4) == '0')
cut = date.substr(5,1);
else
cut = date.substr(4,2);
if(cut == "1")
Namonth = "January";
else if(cut == "2")
Namonth = "February";
else if(cut == "3")
Namonth = "March";
else if(cut == "4")
Namonth = "April";
else if(cut == "5")
Namonth = "May";
else if(cut == "6")
Namonth = "June";
else if(cut == "7")
Namonth = "July";
else if(cut == "8")
Namonth = "August";
else if(cut == "9")
Namonth = "September";
else if(cut == "10")
Namonth = "October";
else if(cut == "11")
Namonth = "November";
else
Namonth = "December";
return Namonth;
}
string StockInfo::line3()
{
string line, cutdate;
if(date.at(6) == '0')
cutdate = date.substr(7,1);
else
cutdate = date.substr(6,2);
line = convertmonth() + " " + cutdate + ", "
+ date.substr(0,4);
return line;
}
void StockInfo::write(OrderLinkedList<Code> OLLCO, Code CO)
{
CO.setcode(stcode);
if(!OLLCO.searchList(CO))
cout << "not found" << endl;
cout << CO.getname();
cout << line3() << endl;
cout << "Opening price: $" << opprice <<endl;
cout << "Daily high price: $" << hiprice << endl;
cout << "Daily low price: $" << loprice << endl;
cout << "Closing price: $" << clprice << endl;
cout << "Shares exchanged: " << volume << endl;
cout << "Daily change: " << (clprice - opprice) / opprice * 100
<< "%" << endl;
}
void StockInfo::setdate(string sdate)
{
date = sdate;
}
void StockInfo::setcode(string scode)
{
stcode = scode;
}
string StockInfo::getcode()
{
return stcode;
}
ostream& operator<< (ostream &strm, StockInfo &theObj)
{
strm << theObj.stcode << "-" << theObj.line3() << endl
<< theObj.hiprice << "-" << theObj.loprice << endl;
return strm;
}
// Specification file for the BinTreeType class
// PRECONDITION for use of this class:
// Data type defining tree node "info" must have operators
// '<', 'cout', and ==', or they must be overloaded
#ifndef BINARYTREE_H
#define BINARYTREE_H
#include <iostream>
using namespace std;
template <class ItemType>
class BinTreeType
{
private:
struct TreeNode
{
ItemType info;
TreeNode *left;
TreeNode *right;
};
TreeNode *root;
// Overloaded functions for recursive actions
void insert(TreeNode *&, TreeNode *&);
void deleteIt(ItemType, TreeNode *&);
void makeDeletion(TreeNode *&);
void destroySubTree(TreeNode *);
void getSucccessor( TreeNode* aNode, ItemType& data);
void copyTree(TreeNode*& copy, const TreeNode* origTree);
// Overloaded traversal functions for recursive actions
void displayInOrder(TreeNode *);
void displayPreOrder(TreeNode *);
void displayPostOrder(TreeNode *);
// Recursive functions for various utility operations
int countNodes(TreeNode* tree);
public:
BinTreeType(); // Constructor
BinTreeType(BinTreeType& origTree); // Copy constructor
void operator= (BinTreeType& origTree); // Overloaded assignment operator
~BinTreeType(); // Destructor
// Tree data insertion, deletion, and searching
void insertNode(ItemType);
bool searchNode(ItemType&);
void deleteNode(ItemType);
// Tree traversal
void displayInOrder();
void displayPreOrder();
void displayPostOrder();
// Utilities for tree operations
int numberOfNodes(); // Count nodes in tree
};
//*************************************************************
//*************************************************************
// Implementation file for the BinTreeType class
//*************************************************************
//*************************************************************
// Constructor
template <class ItemType>
BinTreeType<ItemType>::BinTreeType()
{
root = NULL;
}
// Copy constructor - Utilizes recursive utility function
// copyTree to actually replicate original tree
template <class ItemType>
BinTreeType<ItemType>::BinTreeType(BinTreeType<ItemType>& origTree)
{
copyTree(root, origTree.root);
}
// Overloaded assignment operator - Utilizes recursive utility function
// copyTree to actually replicate original tree
template <class ItemType>
void BinTreeType<ItemType>::operator= (BinTreeType<ItemType>& origTree)
{
destroySubTree(root); // Eliminate any existing nodes in target
copyTree(root, origTree.root); // Copy source to target as part of assignment
}
// Destructor
template <class ItemType>
BinTreeType<ItemType>::~BinTreeType()
{
destroySubTree(root);
}
//*************************************************************
// insert accepts a TreeNode pointer and a pointer to a node. *
// The function inserts the node into the tree pointed to by *
// the TreeNode pointer. This function is called recursively. *
//*************************************************************
template <class ItemType>
void BinTreeType<ItemType>::insert(TreeNode *&nodePtr, TreeNode *&newNode)
{
if (nodePtr == NULL)
nodePtr = newNode; // Insert the node.
else if (newNode->info < nodePtr->info)
insert(nodePtr->left, newNode); // Search the left branch
else
insert(nodePtr->right, newNode); // Search the right branch
}
//**********************************************************
// insertNode creates a new node to hold num as its value, *
// and passes it to the insert function. *
//**********************************************************
template <class ItemType>
void BinTreeType<ItemType>::insertNode(ItemType num)
{
TreeNode *newNode; // Pointer to a new node.
// Create a new node and store num in it.
newNode = new TreeNode;
newNode->info = num;
newNode->left = newNode->right = NULL;
// Insert the node.
insert(root, newNode);
}
//***************************************************
// destroySubTree is called by the destructor. It *
// deletes all nodes in the tree. *
//***************************************************
template <class ItemType>
void BinTreeType<ItemType>::destroySubTree(TreeNode *nodePtr)
{
if (nodePtr != NULL)
{
if (nodePtr->left != NULL)
destroySubTree(nodePtr->left);
if (nodePtr->right != NULL)
destroySubTree(nodePtr->right);
delete nodePtr;
}
}
//***************************************************
// searchNode determines if a value is present in *
// the tree. If so, the function returns true. *
// Otherwise, it returns false. *
//***************************************************
template <class ItemType>
bool BinTreeType<ItemType>::searchNode(ItemType& item)
{
TreeNode *nodePtr = root;
while (nodePtr != NULL)
{
if (nodePtr->info == item)
return true;
else if (item < nodePtr->info)
nodePtr = nodePtr->left;
else
nodePtr = nodePtr->right;
}
return false;
}
//**********************************************
// Function deleteNode triggers the chain of *
// recursive calls to search for and delete *
// target node. *
//**********************************************
template <class ItemType>
void BinTreeType<ItemType>::deleteNode(ItemType item)
{
deleteIt(item, root);
}
//***********************************************
// Function deleteIt recursively searches for *
// the item to delete and calls function *
// makeDeletion to perform the actual deletion. *
//***********************************************
template <class ItemType>
void BinTreeType<ItemType>::deleteIt(ItemType item, TreeNode *&nodePtr)
{
if (item < nodePtr->info)
deleteIt(item, nodePtr->left);
else if (item > nodePtr->info)
deleteIt(item, nodePtr->right);
else
makeDeletion(nodePtr);
}
//***********************************************************
// makeDeletion takes a reference to a pointer to the node *
// that is to be deleted. The node is removed and the *
// branches of the tree below the node are reattached. *
//***********************************************************
template <class ItemType>
void BinTreeType<ItemType>::makeDeletion(TreeNode *&nodePtr)
{
TreeNode *tempNodePtr; // Temporary pointer, used for deletion
ItemType data;
if (nodePtr->right == NULL) // If no right child exists
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->left; // Then reattach the left child
delete tempNodePtr;
}
else if (nodePtr->left == NULL) // If no left child exists
{
tempNodePtr = nodePtr;
nodePtr = nodePtr->right; // Then reattach the right child
delete tempNodePtr;
}
else // If the node has two children
{
// Get data for immediate successor (largest node in right subtree)
getSucccessor(nodePtr,data);
// Move information from successor node to target node
nodePtr->info = data;
deleteIt(data, nodePtr->right); // And delete successor node
}
}
//****************************************************************
// This function scans for the succeeding node in order within *
// a binary tree. It moves the the right child, and then moves *
// down the chain of left children until NULL is reached. It *
// returns the data at the predecessor node by reference. *
//****************************************************************
template <class ItemType>
void BinTreeType<ItemType>::getSucccessor( TreeNode* aNode, ItemType& data)
{
aNode = aNode->right;
while (aNode->left != NULL)
aNode = aNode->left;
data = aNode->info;
}
//****************************************************************
// The displayInOrder member function displays the values *
// in the subtree pointed to by nodePtr, via inorder traversal. *
//****************************************************************
template <class ItemType>
void BinTreeType<ItemType>::displayInOrder()
{
displayInOrder(root);
}
// Recursive function performing traversal
template <class ItemType>
void BinTreeType<ItemType>::displayInOrder(TreeNode *nodePtr)
{
if (nodePtr != NULL)
{
displayInOrder(nodePtr->left);
cout << nodePtr->info << " ";
displayInOrder(nodePtr->right);
}
}
//****************************************************************
// The displayPreOrder member function displays the values *
// in the subtree pointed to by nodePtr, via preorder traversal. *
//****************************************************************
template <class ItemType>
void BinTreeType<ItemType>::displayPreOrder()
{
displayPreOrder(root);
}
// Recursive function performing traversal
template <class ItemType>
void BinTreeType<ItemType>::displayPreOrder(TreeNode *nodePtr)
{
if (nodePtr != NULL)
{
cout << nodePtr->info << " ";
displayPreOrder(nodePtr->left);
displayPreOrder(nodePtr->right);
}
}
//****************************************************************
// The displayPostOrder member function displays the values *
// in the subtree pointed to by nodePtr, via postorder traversal.*
//****************************************************************
template <class ItemType>
void BinTreeType<ItemType>::displayPostOrder()
{
displayPostOrder(root);
}
// Recursive function performing traversal
template <class ItemType>
void BinTreeType<ItemType>::displayPostOrder(TreeNode *nodePtr)
{
if (nodePtr != NULL)
{
displayPostOrder(nodePtr->left);
displayPostOrder(nodePtr->right);
cout << nodePtr->info << " ";
}
}
//****************************************************************
// This function recursively traverses the tree and increments *
// a counter at each node "visit" to count the total number of *
// data nodes in the tree. *
//****************************************************************
template<class ItemType>
int BinTreeType<ItemType>::numberOfNodes()
{
return countNodes(root);
}
// Private function performing recursive count
template<class ItemType>
int BinTreeType<ItemType>::countNodes(TreeNode* tree)
{
if (tree == NULL)
return 0;
else
return countNodes(tree->left) +
countNodes(tree->right) + 1;
}
//******************************************************************
// This function replicates a tree as part of the copy constructor *
// and overloaded assignment operations. *
//******************************************************************
template<class ItemType>
void BinTreeType<ItemType>::copyTree(TreeNode*& copy, const TreeNode* origTree)
{
if (origTree == NULL) // Handle case of empty tree
copy = NULL;
else
{
copy = new TreeNode;
copy->info = origTree->info;
copyTree(copy->left, origTree->left);
copyTree(copy->right, origTree->right);
}
}
#endif
//*********************************************
// The ListNode class creates a type used to *
// store a node of the linked list. *
// PRECONDITIONS: *
// Choice for ItemType implements 'cout' *
// as well as "==" and "<" operators *
//*********************************************
#ifndef OrderOrderLinkedList_H
#define OrderOrderLinkedList_H
template <class ItemType>
class ListNode
{
public:
ItemType info; // Node value
ListNode<ItemType> *next; // Pointer to the next node
// Constructor
ListNode (ItemType nodeValue)
{
info = nodeValue;
next = NULL;
}
};
//*********************************************
// OrderLinkedList class *
//*********************************************
template <class ItemType>
class OrderLinkedList
{
private:
ListNode<ItemType> *head; // List head pointer
ListNode<ItemType> *currentPos; // Pointer to "current" list item
int length; // Length
public:
OrderLinkedList(); // Constructor
~OrderLinkedList(); // Destructor
OrderLinkedList( const OrderLinkedList<ItemType>& anotherList ); // Copy constructor
void operator= ( const OrderLinkedList<ItemType>& ); // Assignment operator
void insertNode(ItemType);
void deleteNode(ItemType);
bool searchList(ItemType& item);
int getLength();
void displayList();
void resetList();
ItemType getNextItem(); // Iterator
bool atEnd();
};
//**************************************************
// Constructor *
// Initial list head pointer and length *
//**************************************************
template <class ItemType>
OrderLinkedList<ItemType>::OrderLinkedList()
{
head = NULL;
length = 0;
}
//**************************************************
// displayList shows the value stored in each node *
// of the linked list pointed to by head. *
// Precondition: "cout" operator enabled for *
// ItemType data type. *
//**************************************************
template <class ItemType>
void OrderLinkedList<ItemType>::displayList()
{
ListNode<ItemType> *nodePtr;
nodePtr = head;
while (nodePtr != NULL)
{
cout << nodePtr->info << endl;
nodePtr = nodePtr->next;
}
}
//**************************************************
// The insertNode function inserts a node with *
// newValue copied to its value member. *
//**************************************************
template <class ItemType>
void OrderLinkedList<ItemType>::insertNode(ItemType newValue)
{
ListNode<ItemType> *newNode, *nodePtr, *previousNode = NULL;
// Allocate a new node & store newValue
newNode = new ListNode<ItemType>(newValue);
// If there are no nodes in the list
// make newNode the first node
if (head == NULL)
{
head = newNode;
newNode->next = NULL;
}
else // Otherwise, insert newNode
{
// Initialize nodePtr to head of list and previousNode to NULL.
nodePtr = head;
previousNode = NULL;
// Skip all nodes whose value member is less
// than newValue.
while (nodePtr != NULL && nodePtr->info < newValue)
{
previousNode = nodePtr;
nodePtr = nodePtr->next;
}
// If the new node is to be the 1st in the list,
// insert it before all other nodes.
if (previousNode == NULL)
{
head = newNode;
newNode->next = nodePtr;
}
else // Otherwise, insert it after the prev. node.
{
previousNode->next = newNode;
newNode->next = nodePtr;
}
}
}
//*****************************************************
// The deleteNode function searches for a node *
// with searchValue as its value. The node, if found, *
// is deleted from the list and from memory. *
//*****************************************************
template <class ItemType>
void OrderLinkedList<ItemType>::deleteNode(ItemType searchValue)
{
ListNode<ItemType> *nodePtr, *previousNode;
// If the list is empty, do nothing.
if (!head)
return;
// Determine if the first node is the one.
if (head->info == searchValue)
{
nodePtr = head->next;
delete head;
head = nodePtr;
}
else
{
// Initialize nodePtr to head of list
nodePtr = head;
// Skip all nodes whose value member is
// not equal to searchValue.
while (nodePtr != NULL && nodePtr->info != searchValue)
{
previousNode = nodePtr;
nodePtr = nodePtr->next;
}
// If nodePtr is not at the end of the list,
// link the previous node to the node after
// nodePtr, then delete nodePtr.
if (nodePtr)
{
previousNode->next = nodePtr->next;
delete nodePtr;
}
}
length--;
}
//**************************************************
// Linear search *
// Post: If found, item's key matches an element's *
// key in the list and a copy of that element has *
// been stored in item; otherwise, item is *
// unchanged. Return value is boolean to indicate *
// status of search. *
//**************************************************
template <class ItemType>
bool OrderLinkedList<ItemType>::searchList(ItemType& item)
{
bool moreToSearch;
ListNode<ItemType>* nodePtr;
nodePtr = head; // Start search from head of list
bool found = false; // Assume value not found
moreToSearch = (nodePtr != NULL);
while (moreToSearch && !found)
{
if (nodePtr->info < item)
{
nodePtr = nodePtr->next;
moreToSearch = (nodePtr != NULL);
}
else if (item == nodePtr->info)
{
found = true;
item = nodePtr->info;
}
else
moreToSearch = false;
}
return found;
}
//**************************************************
// Iterator reset function *
// Resets pointer of current item in list to the *
// head of the list. *
//**************************************************
template <class ItemType>
void OrderLinkedList<ItemType>::resetList()
// Post: Current position has been initialized.
{
currentPos = head;
}
//**************************************************
// Function: Gets the next element in list as
// referenced by currPtr
// Pre: Current position is defined.
// Element at current position is not last in list.
// Post: Current position is updated to next position.
// item is a copy of element at current position.
//**************************************************
template <class ItemType>
ItemType OrderLinkedList<ItemType>::getNextItem()
{
ItemType item;
if (currentPos == NULL)
currentPos = head; // wrap if getnext is called at past-end
//else
item = currentPos->info;
currentPos = currentPos->next;
return item;
}
//**************************************************
// Observer function to return current list length *
//**************************************************
template <class ItemType>
int OrderLinkedList<ItemType>::getLength()
{
return length;
}
//**************************************************
// Observer function to determine if current *
// is the end of the list *
//**************************************************
template <class ItemType>
bool OrderLinkedList<ItemType>::atEnd()
{
if (currentPos == NULL)
return true;
else
return false;
}
//**************************************************
// Copy Constructor *
//**************************************************
template<class ItemType>
OrderLinkedList<ItemType>::OrderLinkedList( const OrderLinkedList<ItemType>& anotherList )
{
ListNode<ItemType>* ptr1;
ListNode<ItemType>* ptr2;
if (anotherList.head == NULL)
head = NULL;
else
{
head = new ListNode<ItemType>(anotherList.head->info);
ptr1 = anotherList.head->next;
ptr2 = head;
while (ptr1 != NULL)
{
ptr2->next = new ListNode<ItemType>(ptr1->info);
ptr2 = ptr2->next;
ptr1 = ptr1->next;
}
ptr2->next = NULL;
}
length = anotherList.length;
}
//**************************************************
// Overloaded Assignment Operator *
//**************************************************
template<class ItemType>
void OrderLinkedList<ItemType>::operator=( const OrderLinkedList<ItemType>& anotherList )
{
ListNode<ItemType>* ptr1;
ListNode<ItemType>* ptr2;
if (anotherList.head == NULL)
head = NULL;
else
{
head = new ListNode<ItemType>(anotherList.head->info);
ptr1 = anotherList.head->next;
ptr2 = head;
while (ptr1 != NULL)
{
ptr2->next = new ListNode<ItemType>(ptr1->info);
ptr2 = ptr2->next;
ptr1 = ptr1->next;
}
ptr2->next = NULL;
}
length = anotherList.length;
}
//**************************************************
// Destructor *
// This function deletes every node in the list. *
//**************************************************
template <class ItemType>
OrderLinkedList<ItemType>::~OrderLinkedList()
{
ListNode<ItemType> *nodePtr, *nextNode;
nodePtr = head;
while (nodePtr != NULL)
{
nextNode = nodePtr->next;
delete nodePtr;
nodePtr = nextNode;
}
}
#endif
#ifndef STRING_TOKENIZER_H
#define STRING_TOKENIZER_H
// This class is designed to manage a line of "tokenized" data
// (comma-separated files). The primary class data member is a
// string object. It includes the ability to reset the delimiter
// from a comma to a different character.
// Strategy: programmer must "reset" the token "pointer" to begin.
// Then, by calling one of the "get" function, they can return the
// next data token separated by the current and next comma (or endline).
// Precondition: Class user has knowledge of number and types
// of tokens in data.
#include<cstdlib>
#include<string.h>
using namespace std;
class StringTokenizer
{
private:
string theLine; // String containing raw data
int currIndex; // Index of current token in focus
char delimiterChar; // Character that is delimiter (default: comma)
string get_a_Token(); // Utility function to extract string tokens
public:
// Default constructor - accepts comma-delimited string to parse
StringTokenizer(string);
// Parameterized constructor - accepts a character other than a comma
// as delimiter.
// Precondition: separator is a single character (non-space)
StringTokenizer(char);
// Parameterized constructor - accepts an initial string to parse and
// a character other than a comma as delimiter.
// Precondition: separator is a single character (non-space)
StringTokenizer(string, char);
// "Set" and "Get" functhions
void setLine(string);
string getLine();
// Iterator to reset token sequence to first token
void reset();
// Returns total number of tokens in line (number of commas + 1)
int numberTokens();
// Observes if pointer to current token is at end of string
bool atEnd();
// Functions to return data tokens based on type
string getStringToken(); // Returns a string token being referenced
char getCharToken(); // Returns an character value being referenced
double getDoubleToken(); // Returns a double value being referenced
int getIntToken(); // Returns an integer value being referenced
};
#endif
// Class to manage "tokenized" data (comma-separated files)
#include<iostream>
#include<string>
using namespace std;
#include "StringTokenizer.h"
// Constructor
// Receive line of comma-delimited data and set index of current
// token to zero
StringTokenizer::StringTokenizer(string line)
{
theLine = line;
currIndex = 0;
delimiterChar = ','; // Default delimiter is comma
}
// Parameterized constructor - accepts a character other than a comma
// as delimiter.
// Precondition: separator is a single character (non-space)
// Postcondtion: data string NOT initialized
StringTokenizer::StringTokenizer(char newDelimiter)
{
currIndex = 0;
delimiterChar = newDelimiter; // Set delimiter to programmer choice
}
// Parameterized constructor - accepts an initial string to parse and
// a character other than a comma as delimiter.
// Precondition: separator is a single character (non-space)
StringTokenizer::StringTokenizer(string line, char newDelimiter)
{
theLine = line;
currIndex = 0;
delimiterChar = newDelimiter; // Set delimiter to programmer choice
}
// "Set" and "Get" functhions
void StringTokenizer::setLine(string line)
{
theLine = line;
}
string StringTokenizer:: getLine()
{
return theLine;
}
// Reset index of current token to zero
void StringTokenizer::reset()
{
currIndex = 0;
}
// Return number of tokens in current string
int StringTokenizer::numberTokens()
{
int lineLength = theLine.length();
int count = 0;
for (int i = 0; i < lineLength; i++)
if (theLine.at(i) == delimiterChar)
count++;
return count + 1; // Return number of tokens as number of commas + 1
}
// To observe if token pointer is at end of string
bool StringTokenizer::atEnd()
{
if (currIndex == theLine.length())
return true;
else
return false;
}
// Return next token as a string object
// Precondition: Token pointer is not at end of string
string StringTokenizer::getStringToken()
{
return get_a_Token();
}
// Return next token as a character object
// Precondition: Token pointer is not at end of string
char StringTokenizer::getCharToken()
{
string tempString;
char outChar;
tempString = get_a_Token();
outChar = tempString[0]; // Extract one char from string
return outChar;
}
// Return next token as a double value
// Precondition: Token pointer is not at end of string
double StringTokenizer::getDoubleToken()
{
char tempCharArray[20];
string tempString;
double outValue;
tempString = get_a_Token();
strcpy(tempCharArray,tempString.data() ); // Convert string to char array
outValue = atof(tempCharArray); // Convert numerator to string
return outValue;
}
// Returns an integer value being referenced
int StringTokenizer::getIntToken()
{
char tempCharArray[20];
string tempString;
int outInt;
tempString = get_a_Token();
strcpy(tempCharArray,tempString.data() ); // Convert string to char array
outInt = atof(tempCharArray); // Convert numerator to string
return outInt;
}
// This utility function retrieves the next token and returns it to
// be correctly typed before the final return from the object function call
string StringTokenizer::get_a_Token()
{
string outString;
int newIndex = theLine.find(delimiterChar,currIndex);
if (newIndex >= 0) // If not last token
{
outString = theLine.substr(currIndex,newIndex - currIndex);
currIndex = newIndex + 1; // Advance to position after next comma
}
else // If last token
{
outString = theLine.substr(currIndex,theLine.length() - currIndex);
currIndex = newIndex + 1; // Advance to position end
}
return outString;
}