C M S C     2 1 4
C o m p u t e r   S c i e n c e   I I
F a l l   2 0 0 2


Item Specifications, Part 2

In Project 2, Item is revised to take a string that may contain blank spaces. For example, you can now initialize an Item object with a string like: "***chocolate*doughnut" (where asterisks are used to represent spaces to make it easier to see).

Use the Tokenizer class to split this into a vector of strings (i.e., into { "chocolate", "doughnut" }), which is saved into a data member.

KEEP the case the same as entered (e.g., if you initialize with "***CHOCOLATE*doughnut", the vector should contain "CHOCOLATE" at element 0, and "doughnut" at element 1).

Since the internal represenation of the food item has changed, compare() is also changed so it compares vectors of strings. The new algorithm for compare() is described below.

Note: compare() is case-INSENSITIVE (as it was in Project 1).

Item

Private Data Members

Declaration Description
vector<string> name Holds the name of a food item (as passed in by the constructor). The name can contain alphanumeric characters, which can contain upper and lower case letters. The name of the food item is now stored in a vector of strings.
int points The number of "points" the item is worth

You may add additional private members, but do NOT remove the data members above.

Public Methods

Note: all the comparison operators do case-insensitive comparisons.

Item( const string & nameIn = "NONE", int pointsIn = 0 ) ;
Default constructor. Calls Tokenizer::split() on nameIn and saves the vector result to name.

Do NOT change the case of the name to lowercase.

string getName() const ;
Concatenates the strings in the vector name, putting a single space between the words. For example, if the vector contains iced, RASPBERRY and teA, then the resulting string returned is "iced*RASPBERRY*teA" (the double quotes indicate where the string begins and ends, and is not part of the string itself, and asterisks are really blank spaces).
int getPoints() const ;
Returns points.
bool setPoints( int pointsIn ) ;
Set points to pointsIn, but only if pointsIn is non-negative. If it's negative, don't change the value of points and return false. If it's non-negative, then update the points, and return true.
bool operator==( const Item & other ) const ;
Returns true if name and other.name are the same (case-insensitive). Implement using compare() (a private method).
bool operator!=( const Item & other ) const ;
Returns true if name and other.name are different (case-insensitive). Implement using compare() (a private method).
bool operator<( const Item & other ) const ;
Returns true if name is "less than" other.name (case-insensitive). Implement using compare() (a private method).
bool operator<=( const Item & other ) const ;
Returns true if name is "less than or equal to" other.name are different (case-insensitive). Implement using compare() (a private method).
bool operator>( const Item & other ) const ;
Returns true if name is "greater than" other.name (case-insensitive). Implement using compare() (a private method).
bool operator>=( const Item & other ) const ;
Returns true if name is "greater than or equal to" other.name are different (case-insensitive). Implement using compare() (a private method).
string toString() ;
Returns a string, which, when printed, prints the item name and points, appropriate to be used in printing ItemArrayList and ItemSortedList. That is, it should be used by their toString() method.

The following methods should be implemented, if you feel they are NECESSARY (meaning that the implicit versions of these methods are inadequate).

Item( const Item &other ) ;
Copy constructor. If you choose to implement, you must use helper methods: freeMem(), init(), and/or copy().
Item &operator=( const Item &other ) ;
Assignment operator. If you choose to implement, you must use helper methods: freeMem(), init(), and/or copy().
~Item();
Destructor. If you choose to implement, you must use helper methods: freeMem(), init(), and/or copy().

You may add additional public methods to support the additional private data members. However, you need to implement the above methods as well.

Private Methods

You are required to implement this method and use it to as a helper for the overloaded relational operators.

static int compare( const vector<string> & one, const vector<string> & two ) ;
Does a case-insensitive comparison of one and two, the parameters of this static method (this can be done by converting both to lower case---hint: use transform in STL).

If one is less than two, return -1.
If one is equal to two, return 0.
If one is greater to two, return 1.

The algorithm is more complicated, and is similar to how one might compare URLs (i.e., if you had to sort URLs, it would be similar to sorting food items).

Step 1 Let i be the index of the last string in one and j be the index of the last string in two.

Step 2a If one[ i ] < two[ j ] then return -1.
Step 2b If one[ i ] > two[ j ] then return 1.
Step 2c If one[ i ] == two[ j ] then decrement i and j (if possible), and start at step 2a.

Step 3 If decrementing i OR j causes either to become -1, then

  • return -1 if i is -1, but j is not,
  • return 1 if j is -1 and i is not, or
  • return 0, if both i and j are -1.

Here's an example of how this works. Suppose one contains { "sugar", "cookie" } and two contains { "chocolate", "chip", "cookie" }. The comparison is made with the last word of both vectors. In this case, both one and two contain "cookie" as the last word.

Since the two are the same, then you back up to compare "sugar" and "chip". The two words are different. In particular,
"sugar" > "chip". That means one > two, so compare() stops and returns 1.

Here's a second example. Suppose one contains { "sugar", "cookie" } and two contains { "cookie" }. Again, start from the last word. In this case, both phrases contain "cookie" as the last word. Now, back up one. However, you can't go back to the previous word in two since it contains only one word. At this point, we are at step 3. Since the number of words in one is greater than two, and the two phrases match so far, then one is greater than two, so 1 is returned (10/8: changed to 1).

Here's a third example. Suppose one contains { "sugar", "cookie" } and two contains { "doughnut" }. The last words are different. In particular, "cookie" is less than "doughnut", so return -1. No other words are compared.

Remember, this is case-INSENSITIVE.

If you do choose to implement the copy constructor, assignment operator, and destructor, implement the following methods and use them as helper functions for the three methods.

There should be a file in the posting account (under Tutorial directory) on writing copy constructors, assignment operator, destructors. You should read that.

void init() ;
Behaves like default constructor.
void copy( const Item & other ) ;
Behaves like copy constructor (no deleting of nodes).
void freeMem() ;
Behaves like destructor.

You may add other private methods.

Other Methods

You should implement the overloaded output operator using the toString() method of Item.


See the class syllabus for policies concerning email
Last Modified: Tue Sep 17 19:01:23 EDT 2002
left up down right home

Web Accessibility