Thread: String Count

  1. #1
    Registered User
    Join Date
    Jun 2007
    Posts
    19

    String Count

    I am working on a function to count the number of times that a string appears in an array. For example, if I had the following array:

    Code:
    char str[][10] = {"John","Mary","Bob","Dueche","John","john","Sam"};
    I would like to find out how many times "John" appeared (I put "john" in the list to make sure that my function would determine the difference).

    My desired result would be to create a frequency array that stores the frequency of the strings from the str array.

    I have the following code below that accurately counts the frequency, however, it creates duplicate entries.

    Code:
    int hist(char StrAry[][MAX_SIZE], int l, int lines)
    {                   
       int i, k;
       
       for(l=0; l<lines; l++)
       {   
          printf("\n%s\t", StrAry[l]);
          k = count(StrAry, l, lines);
          for(i=0; i<k; i++)
             printf("*");  
       }
       printf("\n");
       return 0;
    } 
    int count(char StrAry[][MAX_SIZE], int l, int lines)
    {
       int i,j;
       int k = 0;
       
       for(i=0; i<lines; i++)
       {
          j = strcmp(StrAry[l], StrAry[i]);
          if(j == 0)
             {
               k++; 
             }
       } 
        
       return k;
    
    }
    Any ideas?

    Thanks.

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    You need to keep track of the strings you've already counted. When you start off, looking for "John", you count two instances of that string. Later, when you reach "John" again, you start counting all over again but you shouldn't since you already counted "John" the first time through.

    There are various things you can do, one of which would be to use the current string's index in the count function (your "l" parameter). When you go through and find an instance of the string at an index before the current one, you know you must have counted it earlier and can exit the function returning an invalid count. This invalid value (perhaps a negative) would be an indication in the calling function, hist, not to print out the data.

    I'd suggest changes such as:
    Code:
    void hist(char StrAry[][MAX_SIZE], int lines)
    {                   
        int i, k, l;
       
        for(l=0; l<lines; ++l)
        {   
            k = count(StrAry, l, lines);
            if( k > 0 )
            {
                printf("\n%s\t", StrAry[l]);
                for(i=0; i<k; i++)
                    printf("*");  
            }
        }
        printf("\n");
    }
     
    int count(char StrAry[][MAX_SIZE], int l, int lines)
    {
        int i,j;
        int k = 0;
       
        for(i=0; i<lines; i++)
        {
            j = strcmp(StrAry[l], StrAry[i]);
            if( !j && i >= l ) k++; 
            else if( !j && i < l ) return -1;
        } 
        return k;
    }
    Hasn't been tested at all but it's an idea anyway.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Registered User
    Join Date
    Jun 2007
    Posts
    63
    You are really close, it is simple look my code and compare it to yours. You will surely understand what to change.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *names[] = {"Nikos", "Kostas", "Baggelis", "Nikos", "Giannis", "Nikos", "Ilias"};
    
    int CountWordFreq(char **buffer, char *word);
    
    int main(int argc, char **argv)
    {
    	printf("The name 'Nikos' appears in the array %d times\n", CountWordFreq(names, "Nikos"));
    	return 0;
    }
    
    int CountWordFreq(char **buffer, char *word)
    {
    	int i;
    	int freq = 0;
    
    	for(i = 0; buffer[i]; i++)
    	{
    		if(!strcmp(buffer[i], word))
    			freq++;
    	}
    	return freq;
    }

  4. #4
    Woof, woof! zacs7's Avatar
    Join Date
    Mar 2007
    Location
    Australia
    Posts
    3,459
    @Bokarinho, you're still only going to be counting the first word.
    @kiai_viper, Is it supposed to be case insensitive? Ie "john" differs from "John" ?

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > for(i = 0; buffer[i]; i++)
    So where exactly is the NULL pointer specified in the input array?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Jun 2007
    Posts
    63
    Quote Originally Posted by Salem View Post
    > for(i = 0; buffer[i]; i++)
    So where exactly is the NULL pointer specified in the input array?
    OK, the previous was made very quickly and had some mistakes, the new one right below.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *names[] = {"Nikos", "Kostas", "Baggelis", "Nikos", "Giannis", "Nikos", "Ilias", ""};
    
    int CountWordFreq(char **buffer, char *word);
    
    int main(int argc, char **argv)
    {
    	printf("The name 'Nikos' appears in the array %d times\n", CountWordFreq(names, "Nikos"));
    	return 0;
    }
    
    int CountWordFreq(char **buffer, char *word)
    {
    	int i;
    	int freq = 0;
    
    	for(i = 0; strcmp(buffer[i], ""); i++)
    	{
    		if(!strcmp(buffer[i], word))
    			freq++;
    	}
    	return freq;
    }

  7. #7
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Quote Originally Posted by Bokarinho View Post
    Code:
    	for(i = 0; strcmp(buffer[i], ""); i++)
    	{
    		if(!strcmp(buffer[i], word))
    			freq++;
    	}
    Why not just make the last entry of buffer[] a NULL instead of "", and change the loop condition to:

    Code:
    for(i = 0; buffer[i]; i++)
    That call to strcmp() in the loop condition looks pretty awful

  8. #8
    Registered User
    Join Date
    Jun 2007
    Posts
    19
    Thanks for the responses, I just started classes again and haven't been able to review, test, and implement the recommendations given. Will give an update asap.


    Thanks,


    KiaiViper

  9. #9
    Registered User
    Join Date
    Jun 2007
    Posts
    19
    Once again, thanks for all of the responses.

    @hk_mp5kpdw, your solution seems to be the right fit. All of the strings have been counted accurately, along with their frequency.

    Thanks.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  2. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 05:45 PM
  3. Calculator + LinkedList
    By maro009 in forum C++ Programming
    Replies: 20
    Last Post: 05-17-2005, 12:56 PM
  4. "Operator must be a member function..." (Error)
    By Magos in forum C++ Programming
    Replies: 16
    Last Post: 10-28-2002, 02:54 PM
  5. Replies: 2
    Last Post: 05-05-2002, 01:38 PM