一种函数,用于检查每个元素在数组中出现的次数

时间:2013-11-24 17:24:01

标签: c arrays for-loop

我正在创建一个列出数组的函数,并说明每个元素出现的次数。

到目前为止,我自己想到的是我应该遍历数组并且应该有一个计数器来跟踪它出现的次数,然后是第二个数组来放置该计数器的值来对应到第一个数组中的值。

但我无法找出一种搜索算法来查看每个值是否在循环内重复。

3 个答案:

答案 0 :(得分:2)

代码示例已经简化,并且有更多注释

以下是一些建议的步骤:
1) 假设int a[]已排序(为便于计数)(升序或降序,无关紧要)。
2) 创建单独的数组以保持找到结果其中
第一个 一个,num[]存储唯一值,以及
second cnt[]存储找到的值的数量 3) 循环排序数组。
循环中的 4) ,存储唯一值以及keep数组中的出现次数。

排序例程qsort()是一个概念,如果您刚刚开始,您将在后面学习,(暂时不要分心) 但是要观察部分 此示例解决您的问题,查找评论“Look Here”。如上所述,它循环遍历数组,并存储有关数字何时发生变化以及每个数量变化的信息。

以下是一个小代码示例:

查看评论,了解在哪里集中注意力设置计数器等。

#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 );
}

对于包含的数组示例,以下是使用此代码的结果:

enter image description here

答案 1 :(得分:0)

我发布了一个伪代码,以帮助您使用您说无法理解的算法。我希望这会鼓励你启动代码。

//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
}

答案 2 :(得分:0)

首先,您必须使用您拥有的整数及其出现次数来定义列表

struct linked_list {
    int value;
    int numOf;

    linked_list *next;
};

然后您必须具有操作该列表的功能,例如创建列表,将项目推送到该列表,在该列表中查找节点并将其打印到列表中。

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;
    }
}

您必须学习列表才能了解它们的运作方式。 然后你的代码逻辑就像这样:

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;

(我必须释放列表,但我没有在此代码中:P)

我列出了可能重复的项目/元素。我从数组的开头开始。我检查数组的第一个元素,然后检查它是否在重复列表中。如果我在列表中找不到它,我会在重复列表中创建一个新记录,其中包含1个出现次数。然后我检查剩下的,如果它们出现在列表中,我将出现次数加一,如果不是,我会创建一个新记录。最后,我的列表将包含每个号码及其出现次数。

如果数据差异是常数,则此代码需要O(n)步。如果您的数据差异随元素数量的增加而增加,则需要更多步骤。

在执行步骤数和内存分配方面,这种方法在许多情况下优于排序算法。