I am having a lot of trouble working on this program. i am not sure how to make a linked list work with more than just numbers (i only did basic programming) and the book is just terrible, i was wondering if you guys could help me with writing this one. This is the assignment:

Your assignment is to write a program for a computer dating service. Each client gives you his or her name, phone number, and a list of interests. It is your job to maintain lists of men and women using the service and to match up the compatible couples. You will find more details about the assignment, including the inputs, outputs, and deliverables in the course environment.
Input
data about the clients include
sex
name
phone number
number of interests
interests themselves
matches

Command Processing
NEWCLIENT sex name number of interests interests Add the client to the appropriate list by storing the appropriate information. Attempt to match this new client with a member of the opposite sex. A match occurs when the clients have three or more of the same interests. (You only have to find the first match for each new client.) Make sure you then designate both persons as matched, as described in the section on data structures above. Print the name of the new client, the name of his or her match, and both phone numbers. If no match is found, print an appropriate message.
UNMATCH name Unmatch this name with his or her current match by removing name from the matched person.
PRINTMATCH Print a list of all matched pairs.
PRINTFREE Print the names and phone numbers of clients who are not currently matched.
QUIT Stop processing
Output
Echo print all screen input and output on file "Dates.out."
Data Structures
The problem requires you to maintain two lists of clients, one for men and one for women. When a new client is added to the list, he or she is added to the end of the appropriate list.

Each list element must include all the information for one client: name, phone number, number of interests (maximum number is 10), interests, and the name of this client's current match (empty string if not matched).

i have roughly 24 hours to figure this out, i will be attempting to write this myself in this time but i was hoping you guys could give me some advice as to how you would do this. thanks guys.

Recommended Answers

All 13 Replies

Start by writing a class to store the information related to one client.

Then, write a function to obtain the information from the user and write it into a client record.

Then, write a function to print out the information in a client record.

And, then you can start working on the linked-list structure.

I can't give you more details on that because our policy here is not to just give code to people. You have to work on this yourself and ask questions about specific problems you have along the way. That's the only way to learn.

i completely agree, now do you mean i just make a class to store the information? and how does the linked list come into play? instead of an integer would i use a char to represent each node? i probably seem like an idiot but i am just so confused

alright this is what i have so far, does it look ok? minus the node operators i was using a model from an old linked list program before and i figured i would need those eventually so i left em in.

class ClientInfo
{
private:

        char sex;
        char name[20];
        int phoneNum[8];
        char interests[10];
        char match[20];



        struct ListNode *next;

    ListNode *head;

public:
    //constructor
    ClientInfo()
    {head = NULL;}
    //deconstructor
    ~ClientInfo();

    //LinkedList operations
    void appendNode(char);
    void insertNode(char);
    void deleteNode(char);
    void print() const;

    void ClientInfo::setSex (char S)
    {
        sex = S;
    }
    void ClientInfo::setName (char N)
    {
        name[20] = N;
    }
    void ClientInfo::setPhone (int P)
    {
        phoneNum[8] = P;
    }
    void ClientInfo::setInterests (char Ints)
    {
        for (int x = 0; x < 10; x++)
        {
            interests[x] = Ints;
        }

    }
    void ClientInfo::setMatches(char Match)
    {
        match[20] = Match;
    }

    char ClientInfo::getName()
    {
        return name[20];
    }
    int ClientInfo::getPhone()
    {
        return phoneNum[8];
    }
    char ClientInfo::getInterests()
    {
        return interests[20];
    }
    char ClientInfo::getMatches()
    {
        return match[20];
    }

};

now do you mean i just make a class to store the information?

I remember saying something like that....
"Start by writing a class to store the information related to one client."

how does the linked list come into play?

I'm just trying to get you to solve this problem step by step, to make sure you solve the problems as they come. So, once you have the class to store the info, and the functions to get the info from the user and print it out again, and that you have tested that. Then, you have to start working on the linked-list, because that's what the assignment asks for.

instead of an integer would i use a char to represent each node?

What integer? Why a char instead? This makes no sense to me. Once you have a class for the client-info, your linked-list will just have to store objects of that class. So, the nodes would be something like this:

struct ClientNode {
  ClientInfo client_data;
  ClientNode* next;
};

where ClientInfo would be the class that you have created to store the client information.

Your linked-list class would store a pointer to the ClientNode that sits at the head of the list, and each node's next pointer points to the next node in the list. And the final node would have a NULL next pointer.

But, as I said, start by writing the ClientInfo class and its functions. And proceed incrementally, testing each new function, this is the best way to solve this problem in a timely fashion.

i probably seem like an idiot but i am just so confused

No you don't seem like an idiot. You just seem like a stressed student on a deadline, just proceed incrementally, step-by-step, and all will be well.

alright i have everything you said down to implementing the linked list. i see you added that struct ClientNode part in your last post, where would i put that? around the private members in my earlier post?

There was a bit of a problem here because I wrote my last post at the exact same time as you wrote your last post. So, I didn't see your last post (with the ClientInfo class) before now.

First, the data like name, phone-number, and interests should be stored as std::string (from header <string>), not as the char-arrays that you have. And, as for the "interests", the problem says that there should be many interests recorded for each client, so, you will need to have an array of interests, as well as a count of the number of interests recorded for one client. The best way to record that list of interests is through a C++ class called std::vector, however, I'm afraid you might not be allowed to use it (because these classes (called STL containers) are often not allowed in basic programming assignments, although, in real-life, you'd use them everywhere you can). So, instead, you can use a limited array of interests (e.g., maximum of 10 interests per client). With that in mind, you would get these private data members:

class ClientInfo
{
  private:
    char sex;
    std::string name;
    std::string phoneNum;
    int numberOfInterests;
    std::string interests[10];  // maximum of 10 interests can be listed. 
    std::string match;     // I guess this is the name of the matching client.

  public:

    // ...

};

The "linked-list" data-members and functions that you have in your ClientInfo class should not appear there, they don't belong there. The ClientInfo class only records the data of 1 client, that's all it needs to do. The linked-list implementation will be a completely separate thing. So, get rid of the struct ListNode *next; and ListNode *head; data members, as well as those insert / delete functions, they don't belong there.

Now, for the other public functions that you have in the ClientInfo class that you posted, you probably won't need all of them. Concentrate on implementing the following functions:

class ClientInfo {
  private:
    // .. as above ..
  public:
    //constructor
    ClientInfo() {
      numberOfInterests = 0;  // initial list of interests is empty.
    };

    //destructor
    ~ClientInfo() { };  // notice the { } here, you need to have this.

    /* TODO: implement this function.
     * This function should gather the information from the given string to fill in
     * the fields. By definition, the given string should contain:
     *    sex name numberOfInterests interest1 interest2 interest3 ...
     * This function can be used when you get the command:
     *    NEWCLIENT ...
     * You can simply read the first command "NEWCLIENT" and give the rest 
     * of the string to this function on a newly create ClientInfo object.
     */
    void readInfoFromString(const std::string& clientAttributes) {
      // implementation goes here.
      //  hint: use a class called std::stringstream.
    };

    /* TODO: implement this function.
     * This function should return a string that describes the client.
     * Something like "name sex phone-number" (as specified by the problem).
     * You can use this function when you print out the lists of matched and 
     * free clients.
     */
    std::string getClientDescription() const {
      // implementation goes here.
      //  hint: strings can be concatenated with the + operator.
    };

    /* TODO: implement this function.
     * This function should check if the object matches another client.
     * This should check the condition that the other client is of the 
     * opposite sex, and if there are at least three common interests.
     */
    bool isMatchingClient(const ClientInfo& other) const {
      // implementation goes here.
      if ( sex != other.sex ) {  // true if the two clients have opposite sex.
        // check for common interests.
        //  hint: for every interest in 'interests', check if there is a 
        //        match with one of the 'other.interests'. And count the matches found.
      };
    };

    char getSex() const {
      return sex; 
    };

    std::string getName() const {
      return name;
    };

    std::string getMatch() const {
      return match;
    };

    /* 
     * This function sets the 'match' string.
     * This function can be used to create a match by giving it a name of 
     * a matching partner.
     * This function can also be used to destroy a match (in response to the 
     * 'UNMATCH' command), by giving it an empty string: ""
     */
    void setMatch(const std::string& aMatch) {
      match = aMatch;
    };
};

Now, for the linked-list part. You should create two classes like this (which go after (and outside) your ClientInfo class declaration):

struct ClientNode {
  ClientInfo data;
  ClientNode* next;
};

class ClientList {
  private:
    ClientNode* head;
  public:
    // constructor:
    ClientList() {
      head = NULL;
    };

    // destructor:
    ~ClientList() {
      // here, you need to delete all the nodes, by following the 'next' pointers.
    };

    /* TODO: implement this function.
     * This function adds a Client to the list.
     * This function can be used after having create a new client and determined its 
     * sex. In response to 'NEWCLIENT' command.
     */
    void addClient(const ClientInfo& newClient) {
      // implementation goes here.
      //  hint: when order doesn't matter, the easiest is to add 
      //        the client as the new 'head'.
    };

    /* TODO: implement this function.
     * This function finds a match for the given Client.
     * This function can be used after the 'NEWCLIENT' command.
     * This function can also be used by other functions (see below).
     */
    ClientNode* getMatchingClient(const ClientInfo& aClient) const {
      // implementation goes here.
      //  hint: go through the list (from head, following next-pointers, until NULL)
      //        and use the function 'data.isMatchingClient(aClient)' to determine
      //        if the clients match. If they do, then return the node that matched.
      //        If you reach the end of the list without a match, then return NULL.
    };

    /* TODO: implement this function.
     * This function finds a client based on a given name.
     * This function can be used for a number of things.
     */
    ClientNode* findClientByName(const std::string& aName) const {
      // implementation goes here.
      //  hint: go through the list to find a client node whose (data.getName() == aName).
      //        If found, return that node pointer. Else, return NULL.
    };

    /* TODO: implement this function.
     * This function prints the list of clients without a match.
     * This function can be used in response to the 'PRINTFREE' command.
     */
    void printFreeClients() const {
      // implementation goes here.
      //  hint: go through the list and print each client whose 'match' is empty.
      //  hint: use the getClientDescription() function for the information to print. 
    };

    /* TODO: implement this function.
     * This function prints the list of matches.
     * This function can be used in response to the 'PRINTMATCH' command.
     */
    void printMatches(const ClientList& otherList) const {
      // implementation goes here.
      //  hint: go through the list of clients, and for each one that has a match,
      //        find the corresponding client in the 'otherList' using 
      //        the 'findClientByName' function (and the match-name).
      //        And print those matches.
    };
};

Do not forget to test each function that you write. Start by making sure you can input the information for one client into a ClientInfo object, that you can print out that info again, and that you are able to detect a match between two clients. For example, you can have a simple main function just to test the 'NEWCLIENT' command, as so:

using namespace std;

int main() {

  cout << "Enter a NEWCLIENT command for a male client: " << endl;
  string command_str;
  while( command_str != "NEWCLIENT" )
    cin >> command_str;

  string client_attributes;
  getline(cin, client_attributes);  // get the remaining of the line.

  ClientInfo male_client;     // create a new client object.
  male_client.readInfoFromString( client_attributes );  // read-in the attributes.
  // then, print out the info you got:
  cout << "You have entered client: " << male_client.getClientDescription() << endl;

  // Now, do the same for a female.
  cout << "Enter a NEWCLIENT command for a female client: " << endl;
  command_str = "";
  while( command_str != "NEWCLIENT" )
    cin >> command_str;

  getline(cin, client_attributes);  // get the remaining of the line.

  ClientInfo female_client;     // create a new client object.
  female_client.readInfoFromString( client_attributes );  // read-in the attributes.
  // then, print out the info you got:
  cout << "You have entered client: " << female_client.getClientDescription() << endl;

  // Now, you can check if they match:
  if( male_client.isMatchingClient( female_client ) )
    cout << "The clients you have entered match!" << endl;
  else
    cout << "The clients you have entered do not match.." << endl;

  return 0;
};

The above program not only gives you an example of how to work with the ClientInfo class, but it serves as a test program for you to test if the three functions (readInfoFromString, getClientDescription, and isMatchingClient) work.

Once, you have done that, it will be much easier to implement the linked-list functions.

you have been a great help so far thank you. now how do you use the std::stringstream function? i am not familiar with this and also i am not sure what you meant by the term "concatenated" either.

i am not looking for u to give me the code for this part but maybe an example of something similar.

how do you use the std::stringstream function?

The stringstream class is a way to transform a string into a stream (a stream is what the cout and cin are). Here is a working example:

#include <iostream>
#include <string>
#include <sstream>   // this is the header for the stringstream.

using namespace std;

int main() {
  // Say I create this string:
  string some_string = "This is a sentence with words in it.";

  // Then, I can create a stringstream from that string, as so:
  stringstream ss(some_string);

  // Then, I can use this strinstream object as I would with cin:
  cout << "Individual words in '" << some_string << "' are:" << endl;
  string one_word;
  while( ss >> one_word ) {  // read words until none are left.
    cout << one_word << endl;
  };

  // you can also use this to extract numbers from a string:
  string some_num_str = "3 4 87 32 90 23 42";

  stringstream ss2(some_num_str);
  cout << "Individual numbers in '" << some_num_str << "' are:" << endl;
  int one_num;
  while( ss2 >> one_num ) {
    cout << one_num << endl;
  };

  return 0;
};

The above program should output each separate word on a line, and then each separate integer on a line. The stringstream class is the way that you can extract various words or numbers from a string, with the same logic as you would use to capture words or numbers from cin. The stringstream class also works in reverse, i.e., you can construct a string from words and numbers in the same way as you would output them on cout.

also i am not sure what you meant by the term "concatenated" either.

The term concatenation just means that you construct a string by putting smaller strings end-to-end. Like this:

#include <iostream>
#include <string>

using namespace std;

int main() {
  string concat_sentence = string("This ") + "is " + "a " + "concatenation.";

  cout << concat_sentence << endl;

  return 0;
};

Basically, this is what you need in order to build a string out of many smaller ones.

so does this look right then?

void readInfoFromString(const std::string& clientAttributes)
    {

        std::stringstream ss (clientAttributes);
    };

Yes. Now you can extract the information the same as with cin, but with ss instead.

OK i am now to the getMatchingNode part in the linked list, idk if i have been staring at this computer too long today or what but i cannot think of how to write the code for it. i have it searching through each node until it equals NULL but how do i activate the isMatching bool from the main class

Ok, so I assume you have something like this:

ClientNode* getMatchingClient(const ClientInfo& aClient) const {
  ClientNode* current_node = head;
  while( current_node != NULL ) {
    //.. ?
    current_node = current_node->next;
  };
  return NULL;
};

To check for the match, you have to access the data member of the current node and call the isMatching function on it. As so:

ClientNode* getMatchingClient(const ClientInfo& aClient) const {
  ClientNode* current_node = head;
  while( current_node != NULL ) {
    if( current_node->data.isMatching( aClient ) )
      return current_node;
    current_node = current_node->next;
  };
  return NULL;
};

It's that simple.

Have you implemented the addClient function and destructor? You might want to post that code, because it can be tricky, and I want to make sure it is right.

Hi Mike_2000_17. I am working on the same problem but I am stuck on the logical portion of the program. The problem prompts you to input from file "Client.MF" the attributes of each client including the match. Isn't the point of the linked list to find the match? So why would you have that information prior to utilizing the list. I just don't get it. I don't know if the assignment is poorly written or if it is just me. Can you or somebody please clarify this for me so I can move forward on this problem? Thanks!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.