CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 11 of 11
  1. #1
    Join Date
    Feb 2004
    Posts
    11

    Eliminating duplicate words in random sentences

    In the following code I am outputting a sentence in the form:

    "The <noun><verb> the <noun>."

    The user enters 10 verbs and 10 nouns.

    I use rand and srand to generate random sentences, but I can't use the same
    noun twice in the same sentence.

    Can someone tell me how to go about doing this?

    Should I use a for loop and a temp variable?

    How do I distinguish between one noun and the other?


    Code:
    srand(time(NULL)); // Seed rand()
    
    char sentence[maxSentence+1] = "";// Initialize sentence to null string.
    
    //sentence output in the format "The <noun><verb> the <noun>."
    
    for (int k = 0; k < numSentences; k++)
    {
    strcat(sentence,upperThe); // The
    strcat(sentence,space); // (space)
    strcat(sentence, noun[(rand()%numWords)]->getNoun()); // random noun
    strcat(sentence,space); // (space)
    strcat(sentence, verb[(rand()%numWords)]->getVerb()); // random verb
    strcat(sentence,space); // (space)
    strcat(sentence,lowerThe); // the
    strcat(sentence,space); // (space)
    strcat(sentence, noun[(rand()%numWords)]->getNoun()); // random noun
    strcat(sentence,period); // (period)
    
    cout << sentence << endl;
    
    sentence[0] = '\0'; // Reset sentence to null string for next iteration.
    }

  2. #2
    Join Date
    May 2000
    Location
    Washington DC, USA
    Posts
    715
    This is not the most efficient code and but if the nouns you're working with get's bigger and bigger it gets better. An alternative would keep track of the random number and then if the strstr found a match you could then loop on the random number generator until you found a different one...

    Anyway.. this works but will probable make you wait a couple of nano secons longer for your result....

    Code:
    srand(time(NULL)); // Seed rand()
    
    char sentence[maxSentence+1] = "";// Initialize sentence to null string.
    
    //sentence output in the format "The <noun><verb> the <noun>."
    
    for (int k = 0; k < numSentences; k++)
    {
    strcat(sentence,upperThe); // The
    strcat(sentence,space); // (space)
    strcat(sentence, noun[(rand()%numWords)]->getNoun()); // random noun
    strcat(sentence,space); // (space)
    strcat(sentence, verb[(rand()%numWords)]->getVerb()); // random verb
    strcat(sentence,space); // (space)
    strcat(sentence,lowerThe); // the
    strcat(sentence,space); // (space)
    
    // New Code
    int iRandom = (rand()%numWords);
    for( ; ; )          // infinite loop;  while(TRUE) will work too
    {
         if(!strstr( sentence, noun[iRandom]->getNoun())
         {
               // new noun is not part of the sentence
                strcat(sentence, noun[iRandom]->getNoun()); 
    
               // we added our sencond noun so break out of the infinite loop
                break;
        }
        else
        {
              // new noun already in the sentence so pick another one
               iRandom = (rand()%numWords);
        }
    }
    
    // end New Code
    
    strcat(sentence,period); // (period)
    cout << sentence << endl;
    
    //   sentence[0] = '\0'; // Reset sentence to null string for next 
    
    // better to zap it all the way
    memset( sentence, '\0', sizeof(sentence));    // resets the entire string rather than the first character
    
    iteration.
    Last edited by JMS; February 9th, 2004 at 12:18 PM.

  3. #3
    Join Date
    Feb 2004
    Posts
    11
    JMS thanks for the help.

    The program now outputs sentences like:

    The dog fly the chaircat.

    It looks like the nouns are not repeating, but an extra noun is being added to the end of the sentence. In this case cat.

  4. #4
    Join Date
    May 2000
    Location
    Washington DC, USA
    Posts
    715
    Have you walked through your code to figure out where that is happenning?

    I would check the getNoun() class member first....

    Is this double noun behavior happenning every time or most of the time or just some time? If it's not happenning all the time I would make sure that I'm using "memset" on the sentence buffer before every generation.

    I would also check this line out..

    Code:
    strcat(sentence,period); // (period)
    make sure period isn't set to something whacky like "cat." some of the time..

    Another way to debug your code if you can't get the debugger working right is to print out intermediate output to the screen to make sure you're doing what you think you're doing.

    good luck.

  5. #5
    Join Date
    Feb 2004
    Posts
    11
    JMS thanks again.

    Your code produces a new random noun that does not duplicate the first noun. It prints a new noun for all sentences, but still prints the old one before it (i.e. catdog - dog being the new noun).

    My code seems O.K.

    Here is the line for the ending period.

    Code:
    const char period[] = ".";		// Period

  6. #6
    Join Date
    May 2000
    Location
    Washington DC, USA
    Posts
    715
    Code:
    int iRandom = (rand()%numWords);
    for( ; ; )          // infinite loop;  while(TRUE) will work too
    {
         if(!strstr( sentence, noun[iRandom]->getNoun())
         {
               // new noun is not part of the sentence
                strcat(sentence, noun[iRandom]->getNoun()); 
    
               // we added our sencond noun so break out of the infinite loop
                break;
        }
        else
        {
              // new noun already in the sentence so pick another one
               iRandom = (rand()%numWords);
        }
    }
    Sidney,

    "My code" is calling your code. This is not to say that you're code is wrong since I don't have your code I can't make that judgement. I would suggest that you debug "your code" and "My code" by 1) stepping through the debugger. 2) writing intermediate values to screen.

    The code above will call the line
    Code:
                strcat(sentence, noun[iRandom]->getNoun());
    only once and that is the only line which is concatinationg a noun onto your sentence.

    Now be sure you copied "My code" right and make sure that strcat line only apeares once in the code you're running.

    I would also call the memset just after your definition rather than merely setting the first byte to '\0'.

    Code:
    char sentence[maxSentence+1] = "";// Initialize sentence to null string.
    
    memset( sentence, '\0', sizeof(sentence));

    Good luck and post again once you've narrowed down the problem.

  7. #7
    Join Date
    May 2000
    Location
    Washington DC, USA
    Posts
    715
    Post the code for the function

    getNoun()

    I want to look in there to see what it's doing. Did you write this or did your teacher?

  8. #8
    Join Date
    Feb 2004
    Posts
    11
    I wrote the code I have so far. I've had some help, but most of it is mine. Here is the code:

    2 classes Verb and Noun:

    Code:
    #ifndef problem3_H
    #define problem3_H
    
    
    class Verb
    {
    public:
        Verb( );
        char* getVerb();
    
    private:
        char theVerb[20] ;
    
    } ;
    
    class Noun
    {
    public:
        Noun( );
    	char* getNoun();
    
    private:
        char theNoun[20] ;
        
    } ;
    
    #endif
    Here are the functions:

    Code:
    #include <iostream>
    
    using namespace std;
    
    #include "problem3.h"
    
    Verb::Verb( )
    {
        cin >> theVerb ;
    }
    
    
    Noun::Noun( )
    {
        cin >> theNoun ;
    }
    
    char* Noun::getNoun()
    {
    return theNoun;
    }
    
    char* Verb::getVerb()
    {
    return theVerb;
    }

  9. #9
    Join Date
    May 2000
    Location
    Washington DC, USA
    Posts
    715
    I can take a look at it if you'd like. But you'll need to zip up the project and attach it to the thread.

    I've got three files now I need the code where and how you load it.. also need any txt files if you use those..

  10. #10
    Join Date
    Feb 2004
    Posts
    11
    JMS, thanks for all of your time and help.

    I tried a slightly different approach. The following code works:

    Code:
    int rand_noun1;
    	  int rand_verb1;
          int rand_noun2;
    
      for (int k = 0; k < numSentences; k++)
      {
    	  rand_noun1 = rand()%numWords;
    	  rand_verb1 = rand()%numWords;
          rand_noun2 = rand()%numWords;
    
          while(rand_noun1 == rand_noun2) 
    	  {
          rand_noun2 = rand()%numWords;
    	  }
        strcat(sentence,upperThe);							  // The
    	strcat(sentence,space);								  // (space)
    	strcat(sentence, noun[rand_noun1]->getNoun()); // random noun
    	strcat(sentence,space);								  // (space)
        strcat(sentence, verb[rand_verb1]->getVerb()); // random verb
        strcat(sentence,space);								  // (space)
    	strcat(sentence,lowerThe);							  // the
    	strcat(sentence,space);								  // (space)
    	strcat(sentence, noun[rand_noun2]->getNoun()); // random noun
        strcat(sentence,period);							  // (period)
    
        cout << sentence << endl;
    
        sentence[0] = '\0';			 // Reset sentence to null string for next 
    iteration.

  11. #11
    Join Date
    Aug 2002
    Posts
    78
    They're gettin' a lil' needlessly complex here.

    Assuming numWords is > 1:

    Code:
    int firstNounIndex = rand() % numWords;
    int secondNounIndex = 0;
    
    while ((secondNounIndex = rand() % numWords) == firstNounIndex)
         ;
    ...then assemble your sentence.

    If tighter looking code is important (some pedantics wrongfully disdain assignments in conditional expressions because they once stubbed their toe when they were green), do this:

    Code:
    int firstNounIndex = rand() % numWords;
    int secondNounIndex = rand() % numWords;
    
    while (secondNounIndex == firstNounIndex)
         secondNounIndex = rand() % numWords;
    You can alternatively initialize secondNounIndex to what firstNounIndex is if you are really pedantic^H^H^H^H^H^H^H^H a fussbudget about getting rid of one extra function call:

    Code:
    int firstNounIndex = rand() % numWords;
    int secondNounIndex = firstNounIndex;
    
    while (secondNounIndex == firstNounIndex)
         secondNounIndex = rand() % numWords;
    Last edited by Gorgor; February 11th, 2004 at 11:07 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured