number 在数组中出现的次数

Posted

技术标签:

【中文标题】number 在数组中出现的次数【英文标题】:Number of times number appears in an array 【发布时间】:2013-08-31 07:20:10 【问题描述】:

我在一本 C++ 书中找到了一个练习,上面写着“编写一个函数来计算一个数字在数组中出现的次数。”。一切都很好,程序正在运行。但练习也表明该函数应该是递归的。

我怎样才能使递归函数像这样工作?

#include <iostream>

int count(int number, int array[], int length)

    int counter = 0; 
    for(int i = 0; i < length; i++)
        if(array[i] == number)
            counter++;
    return counter;


int main()

    int numbers[10] = 3,4,1,2,4,5,6,5,4,5;
    int number_to_search = 5;
    std::cout << number_to_search << " appears "
              << count(number_to_search, numbers, 10)
              << " times in the array.";
    return 0;

【问题讨论】:

【参考方案1】:

使用这个count函数:

int count(int number, int array[], int length) 
    if (length == 0) return 0;
    return (number == *array) + count(number, array+1, length-1);

【讨论】:

【参考方案2】:

返回0 + recursive_step1 + recursive_step,而不是您现在拥有的循环和计数器,其中recursive_step 是对count(...) 的调用,您增加了数组指针并减少了length。您的基本情况length == 0,此时您只需返回0

理解递归的一个好方法是逐步研究计算是如何进行的。在您的示例中,您将执行以下操作:

count(5, 3,4,1,2,4,5,6,5,4,5)
0+count(5, 4,1,2,4,5,6,5,4,5)
0+0+count(5, 1,2,4,5,6,5,4,5)
0+0+0+count(5, 2,4,5,6,5,4,5)
0+0+0+0+count(5, 4,5,6,5,4,5)
0+0+0+0+0+count(5, 5,6,5,4,5)
0+0+0+0+0+1+count(5, 6,5,4,5)
0+0+0+0+0+1+0+count(5, 5,4,5)
0+0+0+0+0+1+0+1+count(5, 4,5)
0+0+0+0+0+1+0+1+0+count(5, 5)
0+0+0+0+0+1+0+1+0+1+count(5,)
0+0+0+0+0+1+0+1+0+1+0  <---The last 0 is the base case
3

如果你被允许改变函数规范,你也可以做一些很酷的事情,叫做尾递归。代替return 1 + count(...),将累积的数字作为参数添加到计数:int count(int number, int array[], int length, int acc)

然后执行return count(..., acc+1)return count(..., acc+0)。一些编译器然后能够进行 tail call optimization ,将其转换为编译代码中的循环。与常规递归相比,这可以节省内存。

【讨论】:

感谢您的详细回答 :) 我会查找这个尾递归的东西 :)【参考方案3】:

这样试试怎么样:-

int count(int num, int* arr, int length) 
    if (!length)
        return 0;
    int c = count(num, arr+1, length-1);
    return arr[0] == num? c + 1: c;


int main(void) 
int arr[10] = 3,4,1,2,4,5,6,5,4,5;

std::cout << count(2, arr, 10);

return 0;

【讨论】:

谢谢 :D 这个练习对我来说似乎很愚蠢。我的意思是原始解决方案不是比这更有效吗?或者我应该使用递归来解决这样的问题? 这个练习的重点是练习递归。递归比循环更容易编写和理解有很多问题。【参考方案4】:

这就是你要做的(我不会向你展示任何代码以避免破坏你的练习)。

首先,请记住,为了递归,您的函数需要调用自身。接下来,考虑这两点:

length参数等于0时,count(...)的返回值必须为零 当length参数不为零时,考虑count(...)对于array + 1length-1的返回值;我们称之为prior。如果array[0] 等于number,则当前count(...) 的返回值将等于prior+1,或者当array[0] 不等于number 时返回prior

当您根据此描述编写代码时,请注意在递归函数的开头如何使用 ifif 将您的代码拆分为基本情况 (length == 0) 和递归步骤(基于递归调用计算结果)。这是递归函数的常见结构:每次编写递归代码时都必须重现这种结构。

【讨论】:

【参考方案5】:
#include <iostream>

void count(int number, int array[], int length, int &occurence)

    if (*array == number) ++occurence;  

    if (length == 1)
        return;
    else    
        count(number, array+1, length-1, occurence);


int main()

    int numbers[10] = 3,4,1,2,4,5,6,5,4,5;
    int number_to_search = 5;
    int occurence = 0;
    count(number_to_search, numbers, 10,occurence);
    std::cout << number_to_search << " appears "
              << occurence
              << " times in the array.";

【讨论】:

【参考方案6】:
 #include <iostream>
 #include <ctime>
 #include <cstdlib>
 using namespace std;
 int i, j,n,c=0, k=0;
 int a[1000], b[1000];
 class Array 


    public:
        void input ()
        
            cout<<"Enter how many values: ";
            cin>>n;
        

        void arraySeries ()
        
            cout<<"Array elements: ";
            srand(time(0));
            for (i=0; i<n; i++)
            
                a[i]=rand()%100+1;
                cout<<a[i]<<" ";

            
            cout<<endl<<endl;
            cout<<"Odd elements of array: ";
            for (i=0; i<n; i++)
               
                if(a[i]%2==1)
                
                    b[i]=a[i];
                    k++;
                    cout<<b[i]<<" ";
                

            
        
        // i want to find out how many times an odd number is found in b[i]
        // but i am not being able to do so. SOMEONE PLEASE HELP!!
        void OddSearch ()
        
            cout<<endl<<endl;
            for (int k=1;k<100;k++)
            
                c=0;
                for (i=0;i<n; i++)
                

                    if (b[i]==k)
                    
                        c++;
                    
                    cout<<b[i]<<"occurs"<<c<<"times"<<endl;
                
            
        
 ;

 int main ()
 
    Array obj;
    obj.input();
    obj.arraySeries();
    obj.OddSearch();

    return 0;
 

【讨论】:

【参考方案7】:
#include <stdio.h>

int count(int number,int array[],int size)
   int counter=0;
   if(size == 0) return 0;
   if(array[0] == number)
      counter++;
      return counter+count(number,array+1,size-1);
       
   return count(number,array+1,size-1);    
 

int main() 
 
  int array[] = 1,2,2,4,4,8,7,3,4;
  int size = sizeof(array)/sizeof(int);

  printf("%d",count(2,array,size));

  return 0;    

【讨论】:

以上是关于number 在数组中出现的次数的主要内容,如果未能解决你的问题,请参考以下文章

如何求出数组中出现次数最多的数字(C#实现)

面试题29 数组中出现次数超过一半的数字

剑指offer - 时间效率

136. Single Number - LeetCode

29 数组中出现次数超过一半的数字

剑指offer-数组中重复的数字