In my .h file, I have two functions:
String( const char * s = "");
String( const String & s );
My aim is to convert objects created by these two constructors into linked list. So I write a function for converting:
static ListNode * stringToList(const char *s)
{
ListNode * h = new ListNode(s[0], NULL);
ListNode * c = h;
for(int i = 0; s[i] != '\0'; ++i)
{
c->next = new ListNode(s[i], NULL);
c = c->next;
}
return h;
}
I am aware that maybe in the case of char*s, we can use
String::String( const char * s)
{
ListNode::stringToList(s);
}
But in the case of a string object,
String::String( const String & s )
how can I possibly do that? I am a bit confused by linked list/ Besides, all the functions after this one are using ( const String & s ) parameter. It becomes harder to operate on link list, I am very confused on how to accomplish operations on data by link list while all the parameters called in are "const String & s ". a string object
My entire link.h file:
#include <iostream>
using namespace std;
class String
{
public:
/// Both constructors should construct
/// from the parameter s
String( const char * s = "");
String( const String & s );
String operator = ( const String & s );
char & operator [] ( const int index );
int length() const {return ListNode::length(head);}
int indexOf( char c ) const;
bool operator == ( const String & s ) const;
bool operator < ( const String & s ) const;
/// concatenates this and s
String operator + ( const String & s ) const;
/// concatenates s onto end of this
String operator += ( const String & s );
void print( ostream & out );
void read( istream & in );
~String();
private:
bool inBounds( int i )
{
return i >= 0 && i < length();
}
struct ListNode
{
char info;
ListNode * next;
ListNode(char newInfo, ListNode * newNext)
:info( newInfo ), next( newNext )
{
}
// HINT: some primitives you *must* write and use, recursion?
static ListNode * stringToList(const char *s)
{
ListNode * h = new ListNode(s[0], NULL);
ListNode * c = h;
for(int i = 0; s[i] != '\0'; ++i){
c->next = new ListNode(s[i], NULL);
c = c->next;
}
return h;
}
static ListNode * copy(ListNode * L)
{
return !L ? nullptr : new ListNode(L->info, copy(L->next));
}
static bool equal(ListNode * L1, ListNode * L2)
{
return (L1->info != L2->info) ? false : equal(L1->next, L2->next);
}
static ListNode * concat(ListNode * L1, ListNode * L2)
{
return !L1 ? copy(L2) : new ListNode(L1->info, concat(L1->next, L2));
}
static int compare(ListNode * L1, ListNode * L2)
{
return (!L1 && !L2) ? 0 : (L1->info > L2->info) ? 1 : (L1->info < L2->info) ? -1 : compare(L1->next, L2->next) ;
}
static int length(ListNode * L) // O(N) so call rarely
{
return L == nullptr ? 0 : 1 + length(L->next);
}
};
ListNode * head; // no other data members!! especially no len!
};