I am making a function that lists an array and says how many times each element appears.
What I have thought of on my own so far is i should loop through the array and t
Code example has been simplified, and has more comments
Here are some suggested steps:
1) assuming int a[]
is sorted (for ease of counting) (ascending or descending, it does not matter).
2) Create separate arrays to keep found results where
first one, num[]
stores the unique value, and
second cnt[]
stores the number of that value found.
3) loop through sorted array.
4) in loop, store unique value, and count of occurrence in keep array.
The sorting routine qsort()
is a concept you will learn later if you are just getting started, (don't get distracted with it for now) but do observe the part of this example addressing your question, look for the comment "Look Here". As described above, it loops through the array, and stores information about when numbers change, and how many of each there are.
Here is a small code example:
Look at the comments to know where to focus attention on setting counters etc.
#include <stdio.h>
#define sizea 100 //to make variable declarations easier and consistent
int num[sizea];//unless array has all unique numbers, will never use this many
int cnt[sizea];//same comment
int cmpfunc (const void * a, const void * b);//DISREGARD for now (it just works)
int main(void)
{ //a[] is created here as an unsorted array...
int a[sizea]={1,3,6,8,3,6,7,4,6,9,0,3,5,12,65,3,76,5,3,54,
1,3,6,89,3,6,7,4,6,9,0,4,5,12,65,3,76,5,3,54,
1,9,6,8,3,45,7,4,6,9,0,89,5,12,65,3,76,5,3,54,
6,3,6,8,3,6,7,4,6,9,0,23,5,12,65,3,76,5,3,54,
1,3,6,90,3,6,7,4,6,9,0,5,5,12,65,3,76,5,3,54};
int i, j, ncount;
for(i=0;i<sizea;i++) cnt[i] = -1;
for(i=0;i<sizea;i++) num[i] = -999;
//sort array (AGAIN - DON'T spend time on this part, it just sorts the array)
qsort(a, sizea, sizeof(int), cmpfunc);
// a is NOW SORTED, in ascending order, now loop through...
j=0; //start num and cnt arrays at first element and set ncount to 1
num[j] = a[0];
cnt[j] = 1;
ncount = 1;//start off with at least one of the first number
//***Look Here***//
for(i=0;i<sizea-1;i++)//"sizea - 1" so we do not go past a[sizea-1] elements
{ //a has sizea elements, indexed from 0 to sizea-1
//or a[0] to a[99]
if(a[i+1] != a[i])
{
j++; //new unique number, increment num[] array
num[j] = a[i+1];
ncount = 1; //different number start over
cnt[j] = ncount;//initialize new cnt[j] with 1
}
else
{
cnt[j] = ++ncount; //increment cnt, apply it to array
}
}
i=0;
//We now have a list of unique numbers, and count of each one. Print it out
for(i=0;i<j;i++)
{
printf("number %d occurs %d times\n", num[i], cnt[i]);
}
getchar(); //so results will show.
return 0;
}
//Note num[j] and cnt[j] correspond to each other
//num contains a unique number
//cnt contains the number of occurrences for that number
int cmpfunc (const void * a, const void * b)
{
return ( *(int*)a - *(int*)b );
}
For the array example included, here are the results using this code:
I have posted a pseudocode, to help you with the algorithm which you said you are unable to understand. I hope this will encourage you to start the code.
//store the first number in a variable and find
//how many times it occurs in the array, repeat this for all
//the elements in the array
int current = arr[0];
int i=0, count=0;
for(i=0; i < arr.length;i++){ // loop through all the elements of the array
if(arr[i]==current) {
count++; // if current number is same as the number you are looking for
// then increment the counter
} // end of if-loop
}
At first you must define a list with the integers you have and their number of appearances
struct linked_list {
int value;
int numOf;
linked_list *next;
};
then you must have the functions to operate that list, like creating a list, pushing an item to it, finding a node in that list and print it the list.
linked_list* newItem(int value) {
linked_list * temp = (linked_list *)malloc(sizeof(linked_list));
(*temp).value = value;
(*temp).numOf = 1;
return temp;
}
linked_list* findItem(linked_list *head, int value) {
linked_list *counter = head;
while (counter != NULL && (*counter).value != value) {
counter = (*counter).next;
}
return counter;
}
void pushToList(linked_list **head, linked_list *item) {
(*item).next = *head;
*head = item;
}
void printList(linked_list *head) {
while (head != NULL) {
printf("%d:%d\n", (*head).value, (*head).numOf);
head = (*head).next;
}
}
You must study lists in order to understand how do they operate. Then your code logic goes like this:
linked_list *duplicate = NULL;
int i;
int list[11] = { 1, 2, 3, 4, 1, 2, 3, 4, 0, 1, 2 };
for (i = 0; i < 11; i++) {
linked_list *current = findItem(duplicate, list[i]);
if (current == NULL)
pushToList(&duplicate, newItem(list[i]));
else
(*current).numOf++;
}
printList(duplicate);
while (1);
return 0;
(I must free the list but I didn't in this code :P)
I make a list with the items/elements that may be duplicate. I start from the beginning of the array. I check the first element of the array and then I check if it is on the duplicate list. If I can't find it in the list, I make a new record to the duplicate list with 1 number of appearances. Then I check the rest, if they appear in the list I add the number of appearances by one, if they are not, I make a new record. At the end my list will have every number and their number of appearances.
This code takes O(n) steps if your data difference is a constant. If your data difference grows with the number of elements it would take more steps.
This approach is better than sorting algorithms in many occasions in terms of number of step to execute and memory allocation.