Thread: Statistical Mode Function

  1. #1
    Registered User
    Join Date
    Jan 2009
    Posts
    15

    Statistical Mode Function

    So I'm trying to write a basic stats program with arguments as inputs, I've done min, max, and average, and median should be pretty easy, but I'm stuck on mode (most frequently occuring). I want it to eventually be a proper mode function (ie. bi-modal or more, able to return more than one value if ther is more than one mode).

    This is my code so far, the logic through the mode function is very convoluted and weird, but its the only way I could think of doing it. Theres also alot of re-declaring ints and such I havent cleaned up. Output for mode atm with this code is always zero =/

    any ideas ?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    int array[2];
    int temp[2][2];
    
    int checkint(char s[]) //Checks if string is purely numerical
    {
    	int length = strlen(s); // Define string length
    	for (int i = 0; i < length; i++) // For each character
    	{
    		if (isdigit(s[i])); // If numerical, then do nothing
    		else return 0; //If not, then return 0
    	}
    	return 1;
    }
    
    int* bubble_sort(int *r, int y)
    {
    	int i, j, temp;
    	for (i = 0; i < y-1; i++);
    		for (j = 0; j < y-i-1; j++);
    			if (r[j] > r[j + 1])
    			{
    				temp = r[j];
    				r[j] = r[j + 1];
    				r[j + 1] = temp;
    			}
    	return r;
    }
    
    static int maximum(int r[], int y) //Returns maximum integer
    {
    	int f = 0;
    	for(int i = 0; i < y; i++) //For each int in the array
    	{
    		if (r[i] > f) // If it is larger than previously, store it as new f
    			f = r[i];
    		else;
    	}
    	return f; //Return final f value as maximum
    }
    
    static int minimum(int r[], int y) //Returns minimum integer
    {
    	int f = 100000;
    	for(int i = 0; i < y; i++)// For each int in the array
    	{
    		if (r[i] < f) // If it is smaller than previously, store it as new f
    			f = r[i];
    		else;
    	}
    	return f; //Return final f as minimum
    }
    
    static float average(int r[], int y) //Returns average of array as a floating point
    {
    	float f = 0;
    	for(int i = 0; i < y; i++) //For each int in the array
    		f = f + r[i]; // Add them together
    	f = (float)f / y; //Find the average
    	return f; // And return it
    }
    
    int mode(int *r, int y)
    {
    	int count = 1;
    	int trace = -1;
    	int max = 0;
    	bubble_sort(r, y); //Sort the array
    	temp[0][0] = r[0]; //Add the first int, since it has to be new by default
    	for(int i = 0; i < y; i++) //For each int in the array
    		if(r[i+1] != r[i])
    		{
    			temp[count][0] = r[i+1]; // Add it to the temp array if it is new
    			count++;
    		}
    		else;
    	for(int h = 0; h < count; h++) //Initialize temp[][1] to 0
    		temp[h][1] = 0;
    	count = 1;
    	for(int i = 0; i < y; i++) //For each element in the array
    		if(r[i+1] == r[i]) //If same, then add to count
    			count++;
    		else //If not then store count in respective temp array position
    		{
    			trace++;
    			temp[trace][1];
    			count = 1;
    		}
    	for(int i = 0; i < trace; i++) //For each element in temp, test for max
    		if(temp[i][1] > max)
    			max = temp[i][1]; 
    	//Only return the one value for now, though the infrastructure is there now to return more in the future
    			
    	return max;
    }
    
    int main(int argc, char *argv[])
    {
    	int temp = (argc - 2);
    	array[temp];
    	if(argc < 2)  //Check if enough arguments have been supplied
    	{
    		printf("Too few arguments for this program.\n");
    		exit(EXIT_FAILURE); //If not then exit
    	}
    	else 
    	{
    		for (int i = 1; i < argc; i++) //For every argument provided (excluding 0)
    		{
    			int ans = atoi(argv[i]); //Find the int equivalent
    			int var = (i-1);
    			array[var] = ans; //Store it in the array
    		}
    		int max = maximum(array, (argc-1)); //Call the functions
    		int min = minimum(array, (argc-1));
    		float avrg = average(array, (argc-1));
    		int *f;
    		f = &(array[0]);
    		int mod = mode(f, (argc-1));
    		
    		printf("The maximum is %d\n", max);
    		printf("The minimum is %d\n", min);
    		printf("The average is %6.2f\n", avrg);
    		printf("The mode is %d\n", mod);
    	}
    	// Exit indicating success
    	exit(EXIT_SUCCESS);
        return 0;
    }
    what im trying to get to in the mode function is a condensed 2-d array which has all the values from the original array in temp[h][0], but with repeated values removed, and with the respective count for each number in the corresponding temp[h][1] position.
    Last edited by h4rrison.james; 01-16-2009 at 08:37 AM.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    You might want to look at Adak's comment in this short thread:
    http://cboard.cprogramming.com/showt...ight=find+mode
    And maybe do a search of cprogramming.com yourself too, there's been at least a few threads dedicated to this in the short time I've been around.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User
    Join Date
    Jan 2009
    Posts
    15
    I've looked through most of the ones I could find that were C (not C++, that rules out quite alot), and they were all dealing with a single mode returned (ie an int), so they approached it differently than to how i have.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by h4rrison.james View Post
    I've looked through most of the ones I could find that were C (not C++, that rules out quite alot), and they were all dealing with a single mode returned (ie an int), so they approached it differently than to how i have.
    Hey I found the one I was thinking of ("...meaning if there is more than one mode it needs to output the numbers that are all tied for the most used.) I know it has to use arrays in one way or another..."):
    http://cboard.cprogramming.com/showt...highlight=mode
    What a nice guy I am! It's in C, but I don't know if it will be of use to you or not.

    I also suspect Adak's method can be easily adapted to keep ties.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    Registered User
    Join Date
    Jan 2007
    Location
    Euless, TX
    Posts
    144
    Code:
    	for(int i = 0; i < y; i++) //For each int in the array
    		if(r[i+1] != r[i])
    		{
    			temp[count][0] = r[i+1]; // Add it to the temp array if it is new
    			count++;
    		}
    Aren't you exceeding the index in your "if" statement. For example, if y = 2, the second time through the loop, the r[i+1] will be r[2]. Your index maximum should be 1, should it not? 'y' is the length of the array?

    Then to prevent going out of bounds (surprised you don't get some sort of crash) your "for loop" should be "i < y-1".

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    15
    Yer you were right kcpilot, though that didnt fix the function... :S
    In the end, and following the advice of the last post of the thread you linked MK27, I rewrote the function so it is now alot simpler. It passes through once looking for the largest frequency, then passes again looking for any frequencies equal to that frequency, and printing the results. Only problem is my bubble sort doesnt seem to be working, for 1 2 1 2 mode returns 1,2,2 :S
    For 1 1 2 2 though, it returns 1,2

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <ctype.h>
    #include <string.h>
    
    int array[2];
    int temp[2][2];
    
    int checkint(char s[]) //Checks if string is purely numerical
    {
    	int length = strlen(s); // Define string length
    	for (int i = 0; i < length; i++) // For each character
    	{
    		if (isdigit(s[i])); // If numerical, then do nothing
    		else return 0; //If not, then return 0
    	}
    	return 1;
    }
    
    int* bubble_sort(int *r, int y)
    {
    	int i, j, temp;
    	for (i = 0; i < y-1; i++);
    		for (j = 0; j < y-i-1; j++);
    			if (r[j] > r[j + 1])
    			{
    				temp = r[j];
    				r[j] = r[j + 1];
    				r[j + 1] = temp;
    			}
    	return r;
    }
    
    static int maximum(int r[], int y) //Returns maximum integer
    {
    	int f = 0;
    	for(int i = 0; i < y; i++) //For each int in the array
    	{
    		if (r[i] > f) // If it is larger than previously, store it as new f
    			f = r[i];
    		else;
    	}
    	return f; //Return final f value as maximum
    }
    
    static int minimum(int r[], int y) //Returns minimum integer
    {
    	int f = 100000;
    	for(int i = 0; i < y; i++)// For each int in the array
    	{
    		if (r[i] < f) // If it is smaller than previously, store it as new f
    			f = r[i];
    		else;
    	}
    	return f; //Return final f as minimum
    }
    
    static float average(int r[], int y) //Returns average of array as a floating point
    {
    	float f = 0;
    	for(int i = 0; i < y; i++) //For each int in the array
    		f = f + r[i]; // Add them together
    	f = (float)f / y; //Find the average
    	return f; // And return it
    }
    
    static void mode(int *r, int y)
    {
    	int largest_yet, ccount = 1, pcount = 0;
    	bubble_sort(r, y);
    	for(int i = 0; i < y; i++)
    	{
    		if(r[i+1] == r[i])
    			ccount++;
    		else
    		{
    			if(ccount > pcount)
    			{
    				largest_yet = r[i];
    				pcount = ccount;
    				ccount = 1;
    			}
    			else
    				ccount = 1;
    		}
    	}
    	printf("The mode(s) are: %d", largest_yet);
    	ccount = 1;
    	for(int i = 0; i < y; i++)
    	{
    		if(r[i+1] == r[i])
    		   ccount++;
    		else
    		{
    			if(ccount == pcount && r[i] != largest_yet)
    			{
    				printf(", %d", r[i]);
    				ccount = 1;
    			}
    			else
    				ccount = 1;
    		}
    	}
    	printf("\n");
    }
    
    int main(int argc, char *argv[])
    {
    	int temp = (argc - 2);
    	array[temp];
    	if(argc < 2)  //Check if enough arguments have been supplied
    	{
    		printf("Too few arguments for this program.\n");
    		exit(EXIT_FAILURE); //If not then exit
    	}
    	else 
    	{
    		for (int i = 1; i < argc; i++) //For every argument provided (excluding 0)
    		{
    			int ans = atoi(argv[i]); //Find the int equivalent
    			int var = (i-1);
    			array[var] = ans; //Store it in the array
    		}
    		int max = maximum(array, (argc-1)); //Call the functions
    		int min = minimum(array, (argc-1));
    		float avrg = average(array, (argc-1));
    		int *f;
    		f = &(array[0]);
    		
    		printf("The maximum is %d\n", max);
    		printf("The minimum is %d\n", min);
    		printf("The average is %6.2f\n", avrg);
    		mode(f, (argc-1));
    	}
    	// Exit indicating success
    	exit(EXIT_SUCCESS);
        return 0;
    }
    ccount stands for current count
    pcount for previous.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. dllimport function not allowed
    By steve1_rm in forum C++ Programming
    Replies: 5
    Last Post: 03-11-2008, 03:33 AM
  2. Including lib in a lib
    By bibiteinfo in forum C++ Programming
    Replies: 0
    Last Post: 02-07-2006, 02:28 PM
  3. Game Pointer Trouble?
    By Drahcir in forum C Programming
    Replies: 8
    Last Post: 02-04-2006, 02:53 AM
  4. Problem with Visual C++ Object-Oriented Programming Book.
    By GameGenie in forum C++ Programming
    Replies: 9
    Last Post: 08-29-2005, 11:21 PM
  5. Replies: 5
    Last Post: 02-08-2003, 07:42 PM