Thread: storing alot of variables...

  1. #1
    Registered User
    Join Date
    Oct 2006
    Location
    Omaha, Nebraska
    Posts
    116

    storing alot of variables...

    I'm working on a program that prints out the Histogram of a given sentence. My problem is that I need to store a large number of variables to check against (the alphabet). But I don't want to have 26 different variables. Is there better way to do this? Thanks.

  2. #2
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    An array of 26 integers.

  3. #3
    Registered User
    Join Date
    Oct 2006
    Location
    Omaha, Nebraska
    Posts
    116
    right, I need to count them though.
    So for example, I need to compare each of the characters of the users input and increment the the counter corresponding to that variable.

    Here's what I have so far.

    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    #define MAX 1000
    #define ALPHA 26
    
    
    int main(void)
    {
    	int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z = 0; //*sigh* find a way to store this in a better way
    	char input[MAX];
    	int ctr;
    	printf("program running\n");
    	fgets(input, sizeof(input), stdin);
    
    
    	while(input[ctr] != EOF)
    	{
    		switch(input[ctr])
    		{
    			case 'a': 
    				++a;
    				++ctr;
    			case 'b': 
    				++b;
    				++ctr;
    			case 'c': 
    				++c;
    				++ctr;
    			case 'd':
    				++d;
    				++ctr;
    			case 'e':
    				++e;
    				++ctr;
    			case 'f': 
    				++f;
    				++ctr;
    			case 'g':
    				++g;
    				++ctr;
    			case 'h':
    				++h;
    				++ctr;
    			case 'i':
    				++i;
    				++ctr;
    			case 'j':
    				++j;
    				++ctr;
    			case 'k':
    				++k;
    				++ctr;
    			case 'l':
    				++l;
    				++ctr;
    			case 'm':
    				++m;
    				++ctr;
    			case 'n':
    				++n;
    				++ctr;
    			case 'o':
    				++o;
    				++ctr;
    			case 'p':
    				++p;
    				++ctr;
    			case 'q':
    				++q;
    				++ctr;
    			case 'r':
    				++r;
    				++ctr;
    			case 's':
    				++s;
    				++ctr;
    			case 't':
    				++t;
    				++ctr;
    			case 'u':
    				++u;
    				++ctr;
    			case 'v':
    				++v;
    				++ctr;
    			case 'w':
    				++w;
    				++ctr;
    			case 'x':
    				++x;
    				++ctr;
    			case 'y':
    				++y;
    				++ctr;
    			case 'z':
    				++z;
    				++ctr;
    		}
    		
    	
    	printf("a = %d \n", a);
    	printf("b = %d \n", b);
    	printf("c = %d \n", c);
    	printf("d = %d \n", d);
    	printf("e = %d \n", e);
    	printf("f = %d \n", f);
    	printf("g = %d \n", g);
    	printf("h = %d \n", h);
    	printf("i = %d \n", i);
    	printf("j = %d \n", j);
    	printf("k = %d \n", k);
    	printf("l = %d \n", l);
    	printf("m = %d \n", m);
    	printf("n = %d \n", n);
    	printf("o = %d \n", o);
    	printf("p = %d \n", p);
    	printf("q = %d \n", q);
    	printf("r = %d \n", r);
    	printf("s = %d \n", s);
    	printf("t = %d \n", t);
    	printf("u = %d \n", u);
    	printf("v = %d \n", v);
    	printf("w = %d \n", w);
    	printf("x = %d \n", x);
    	printf("y = %d \n", y);
    	printf("z = %d \n", z);
    	return 0;
    	
    	}
    }
    and, please, feel free to critique my code.

    Thanks

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Firstly, I think that your loop should test for the null character, not EOF.

    Next, you did not quite get what rags_to_riches was getting at.

    If you are not willing to rely on ASCII, then you can define:
    Code:
    size_t getLetterIndex(char letter)
    {
        switch (letter)
        {
        case 'A':
        case 'a': return 0;
        // ...
        case 'Z':
        case 'z': return 25;
        default: return 26; // Not a letter!
        }
    }
    Upon which counting is easy:
    Code:
    int letters[26] = {0};
    // ...
    for (ctr = 0; input[ctr] != '\0'; ++ctr)
    {
        unsigned int letter_index = getLetterIndex(input[ctr]);
        if (letter_index != 26)
        {
            ++letters[letter_index];
        }
    }
    (You may wish to give 26 a name instead of using it as a magic number.)

    Now, printing them could be as simple as:
    Code:
    const char *alphabet = "abcdefghijklmnopqrstuvwxyz";
    for (i = 0; i < 26; ++i)
    {
        printf("&#37;c = %d\n", alphabet[i], letters[i]);
    }
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Oct 2006
    Location
    Omaha, Nebraska
    Posts
    116
    OOOH!
    ok, sorry rags_to_riches, yeah, I didn't understand what you where hinting towards.
    I'll re-tool it so that it works off of the ascii character set instead of hard coding the entire thing.
    Thanks.

  6. #6
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Think of an array of 26 int's, where a=0, b= 1, c=2, etc.

    Now a simple loop can save a lot of code and variables:

    Code:
    /* let's take the case where you already have the string in a string buffer, and properly 
        terminated */
    
    for(i = 0; string_buffer[i] != '\n'; i++)   {
       //handles lowercase, you'll need logic to handle uppercase as well, unless both cases are  
       // treated the same in your histogram.
       letter = string_buffer[i];
       number = letter - 'a';
       array[number]++;
    }
    This is called distribution counting, and is a neat trick to know for all kinds of programs.

    If the number - 'a' stuff confuses you, just make your array larger than the largest char value you'll be entering into the array. Then this works:

    array[letter]++;

    Switch statements should always have break statements, unless it's CLEARLY shown why not.

  7. #7
    Registered User
    Join Date
    Oct 2006
    Location
    Omaha, Nebraska
    Posts
    116
    OK, I'm still stumped. I've implemented the code you posted in the example but I'm still confused. I just can't figure out how to get it to print out the proper information. I'd like to figure it out but I can't find anything useful on Distribution Counting on google or wikipedia. Could you point me in the right direction of some reading that might shed some more light on my problem? Thanks again.

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Quote Originally Posted by MikeyIckey View Post
    OK, I'm still stumped. I've implemented the code you posted in the example but I'm still confused. I just can't figure out how to get it to print out the proper information. I'd like to figure it out but I can't find anything useful on Distribution Counting on google or wikipedia. Could you point me in the right direction of some reading that might shed some more light on my problem? Thanks again.
    Well, if you didn't adapt the code to your program, you may have it goofed up. The code was meant to be more of pseudo-code than actual "cut and paste", stuff.

    But I'm thinking you know that, so maybe I goofed - it happens.

    I've heard the term "bucket sorting" used for this as well, but "bucket sorting" just doesn't sound like a good name for it, so I use distribution counting.

    To print up the results:

    Code:
    for(i = 0; i < MaxsizeArray; i++)  
       printf("&#37;10d", Array[i]);   //the Array here is the integer array, not your input array
    The 10 gives you 8 columns, evenly spaced, across an 80 column display.

    Mikey, please post your current code, if the above doesn't fix it, and don't wait - it's easy to fix.

    I seldom see distribution counting mentioned anywhere on programming websites. I am not sure why, I use it in puzzle programs, frequently.
    Last edited by Adak; 05-19-2008 at 06:24 PM.

  9. #9
    Registered User
    Join Date
    Oct 2006
    Location
    Omaha, Nebraska
    Posts
    116
    Here's what I have so far:
    Code:
    #include <stdio.h>
    #include <ctype.h>
    
    #define ALPHA 26
    
    
    int main(void)
    {
    	char input[ALPHA];
    	char array [ALPHA];
    	char letter;
    	int number;
    	int i;
    
    	printf("program running\n");
    	
    	fgets(input, sizeof(input), stdin); //easier and safer then other things
    
    	for(i = 0; input[i] != '\n'; ++i)//heres where I think I buggered up.
    	{
    		letter = input[i]; 
    
    		number = letter - 'a';
    
    		array[++number];
    	}
    	
    	for(i = 0; array[i] != '\n'; ++i)
    	{
    		printf("&#37;i", array[i]);
    	}
    }

  10. #10
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Mikey, you need to re-read my post. You're doing something quite different. Note that your array[] is a char, and should be an integer, for distribution counting. (It can be done with char's, but it is also confusing, imo.) You have one char array already, and we're counting here - count with integers, even if it can be done with char's, later on.

    The increment of number goes OUTSIDE the square brackets. ++i is not the standard idiom for this for loop, and array's always run from the zero'th element to the maximum size of the array - 1.

    Unless you have a particular reason to change the standard idiom, memorize them, and use them.

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    First,
    Code:
    char array [ALPHA];
    1. I would not use "array" as a variable name. I would make it something like letter_count.
    2. It should be an array of ints, not chars (although char will work, as it is often equal to an int, or more likely an unsigned int), as you are using this to count the frequency of each letter in the alphabet.
    3. The contents of this array need to be initialized to zero before you start.

    Second,
    Code:
    array[++number];
    The number inside the square brackets is the index into the array. You do not want to increment the index, you want to increment what's in the array at the index indicated by number.

    Finally,
    Code:
    for(i = 0; array[i] != '\n'; ++i)
    There will be no newline (\n) in this array. Therefore, the control statement in this for loop needs to be changed so that it's valid for the length of the array.

  12. #12
    Registered User
    Join Date
    Oct 2006
    Location
    Omaha, Nebraska
    Posts
    116
    Sorry about not posting anything new to the thread, I've been reading up a lot on how to implement this algorithm and re-reading the thread. I'll post what I have soon. Thanks again for everyone's help so far.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Father and Son Variables
    By khdani in forum Linux Programming
    Replies: 3
    Last Post: 11-28-2008, 06:42 PM
  2. Replies: 15
    Last Post: 09-30-2008, 02:12 AM
  3. storing variables permanentely
    By Saimadhav in forum C++ Programming
    Replies: 8
    Last Post: 08-09-2008, 09:15 PM
  4. hwnd and variables in them
    By underthesun in forum Windows Programming
    Replies: 6
    Last Post: 01-16-2005, 06:39 PM
  5. Variable Storing in memory
    By karb0noxyde in forum C++ Programming
    Replies: 7
    Last Post: 10-11-2004, 07:31 PM