2014-09-30 43 views
2

如何編寫一個函數來查找數組中的最大值以及值出現在數組中的次數?我們不得不使用遞歸來解決這個問題。陣列中的最大值及其頻率

到目前爲止,我在想它應該是這樣的:

int findMax(int[] a, int head, int last) 
{ 
    int max = 0; 

    if (head == last) { 
     return a[head]; 
    } 
    else if (a[head] < a[last]) { 
     count ++; 
     return findMax(a, head + 1, last); 
    } 
} 

我不知道這是否會雖然返回絕對值的最高值,和IM不完全知道如何改變什麼,我有

+1

你的想法是什麼?你將如何使用遞歸來處理這些關於數組的信息? – abiessu 2014-09-30 22:37:13

+0

要有效地使用遞歸,首先需要建立一個基本案例,一旦解決了整個問題,就可以避免遞歸。其次,你必須找到一些規則,使你從第一次遞歸函數調用到解決問題的進度。第三,通過遞歸調用函數來結合進度,直到第一步到達基本情況。 – JGroven 2014-09-30 23:33:10

+0

將其分解爲兩部分。首先編寫一個遞歸函數來查找最大值。然後添加一種方法來跟蹤它發生的次數。 – molbdnilo 2014-09-30 23:46:06

回答

0

你並不遠。

爲了節省頻率和最大值,你可以保留一個指向結構體的指針,然後將指針傳遞給數組的開始,你想要經過的長度和指向這個結構體的指針。 請記住,您應該使用limits.h中的INT_MIN作爲您的初始最大值(請參閱下面的代碼中的reset(maxfreq *)),因爲int可以帶有負值。

下面的代碼做遞歸作業:

#include <limits.h> 

typedef struct { 
    int max; 
    int freq; 
} maxfreq; 

void reset(maxfreq *mfreq){ 
    mfreq->max = INT_MIN; 
    mfreq->freq = 0; 
} 

void findMax(int* a, int length, maxfreq *mfreq){ 

    if(length>0){ 
     if(*a == mfreq->max) 
      mfreq->freq++; 
     else if(*a > mfreq->max){ 
      mfreq->freq = 1; 
      mfreq->max = *a; 
     } 

     findMax(a+1, length - 1, mfreq); 
    } 
} 

findMax的呼叫將本身記得多次初始長度加1,每次遞增提供指針和處理相應元件,因此這基本上只是經歷了a中的所有元素一次,沒有奇怪的分裂。

+0

當然,初始最小值也可以設置爲陣列中的第一個值... – abiessu 2014-10-01 02:27:49

+0

那麼,這會搞亂頻率計數,不是嗎? – pevasquez 2014-10-01 04:22:03

+0

此外,這意味着修改/複製傳遞的數組,並執行額外的傳遞。另外,我知道這是一個C的問題,但是'reset'函數可以爲C++中的一個漂亮的maxfreq構造函數提供:) – pevasquez 2014-10-01 04:32:03

0

這正常工作與我:

#include <stdio.h> 
#include <string.h> 

// define a struct that contains the (max, freq) information 
struct arrInfo 
{ 
    int max; 
    int count; 
}; 

struct arrInfo maxArr(int * arr, int max, int size, int count) 
{ 

    int maxF; 
    struct arrInfo myArr; 

    if(size == 0) // to return from recursion we check the size left 
    { 
     myArr.max = max; // prepare the struct to output 
     myArr.count = count; 
     return(myArr); 
    } 

    if(*arr > max) // new maximum found 
    { 
     maxF = *arr; // update the max 
     count = 1; // initialize the frequency 
    } 
    else if (*arr == max) // same max encountered another time 
    { 
     maxF = max;  // keep track of same max 
     count ++;  // increase frequency 
    } 
    else    // nothing changes 
     maxF = max; // keep track of max 


    arr++;  // move the pointer to next element 
    size --; // decrease size by 1 

    return(maxArr(arr, maxF, size, count)); // recursion 

} 

int main() 
{ 
    struct arrInfo info; // return of the recursive function 

    // define an array 
    int arr[] = {8, 4, 8, 3, 7}; 

    info = maxArr(arr, 0, 5, 1); // call with max=0 size=5 freq=1 


    printf("max = %d count = %d\n", info.max, info.count); 
    return 0; 
} 

運行時,它輸出:

max = 8 count = 3 

注意
在我的代碼示例中,我假定的數字爲正(初始化max0),我不知道你的要求,但你可以詳細說明。

+1

只要將max初始化爲'INT_MIN'(在limits.h中定義),這就避免了負數int :) – Rerito 2014-10-01 15:20:49

+0

初始化'freq = 1'是一個問題,如果最初的'max'值最終結束。結果是在1以外。最好用'freq = 0'來初始化。 – chux 2014-10-01 16:51:44

+0

@chux:你對極端安全的權利'freq'可以更好地初始化爲'0',但如果用戶用'initial max'作爲'real max'調用函數,那真的是無意義的行爲!但我承認你的建議在所有情況下 – chouaib 2014-10-01 23:49:42

3

將初始值max設置爲INT_MIN解決了許多問題。 @Rerito

但是,OP使用迭代遍歷數組的每個成員並引發每個元素的遞歸調用。因此,如果數組有1000 int,則會有大約1000個嵌套調用。

甲分而治之方法:

如果數組長度爲0或1,處理它。否則從第一和第二半找到最大的答案。酌情合併結果。除以2,1000元素數組的堆棧深度使用不會超過10個嵌套調用。

注意:無論採用哪種方式,呼叫次數都相同。不同之處在於嵌套的最大程度。在簡單的for()循環就足夠的情況下使用遞歸是有問題的。爲了征服一個更復雜的評估是遞歸的力量,因此這種方法。


要找到最大和使用O(LOG 2(長度))堆棧深度使用它的頻率:

#include <stddef.h> 

typedef struct { 
    int value; 
    size_t frequency; // `size_t` better to use that `int` for large arrays. 
} value_freq; 

value_freq findMax(const int *a, size_t length) { 
    value_freq vf; 

    if (length <= 1) { 
    if (length == 0) { 
     vf.value = INT_MIN; // Degenerate value if the array was size 0. 
     vf.frequency = 0; 
    } else { 
     vf.value = *a; 
     vf.frequency = 1; 
    } 
    } else { 
    size_t length1sthalf = length/2; 
    vf = findMax(a, length1sthalf); 
    value_freq vf1 = findMax(&a[length1sthalf], length - length1sthalf); 
    if (vf1.value > vf.value) 
     return vf1; 
    if (vf.value == vf1.value) 
     vf.frequency += vf1.frequency; 
    } 
    return vf; 
} 
0

提交作業的reqirements至少是值得懷疑的。僅供參考,這裏是如何應該這樣做在實際的代碼(解決您的分配,是指其他的答案):

int findMax(int length, int* array, int* maxCount) { 
    int trash; 
    if(!maxCount) maxCount = &trash; //make sure we ignore it when a NULL pointer is passed in 

    *maxCount = 0; 
    int result = INT_MIN; 
    for(int i = 0; i < length; i++) { 
     if(array[i] > result) { 
      *maxCount = 1; 
      result = array[i]; 
     } else if(array[i] == result) { 
      (*maxCount)++; 
     } 
    } 
    return result; 
} 

永遠要做的事直線前進,你可以。

+0

我看不到在這段代碼中遞歸! – chouaib 2014-10-01 23:52:00

+0

@chouaib它不應該在那裏。在這種情況下,使用遞歸不符合KISS,並且我明確表示這不是OP分配的解決方案。 – cmaster 2014-10-02 11:02:44