2017-03-10 2 views
-1

Gibt es diese rekursive Funktion irgendwie eleganter? Ich möchte die Funktion so machen, dass es keinen wiederholten Code gibt.Diese Funktion "eleganter" machen C++

int findMaximumValue(int list[], int first, int last) 
{ 
    if (first == last) 
     return list[first]; 
    else { 
     if (list[first] > findMaximumValue(list, first + 1, last)) 
      return list[first]; 
     else 
      return findMaximumValue(list, first + 1, last); 
    } 
} 
+9

Ist die Funktion der Arbeit, wie es sollte? Wenn Sie eine Code-Überprüfung wünschen, senden Sie diese bitte stattdessen auf http://codereview.stackexchange.com/. –

+0

Ja, und danke, ich poste es stattdessen dort. – kekstorm

+1

Nein, es hat keine falsche Komplexität. –

Antwort

1

Es gibt zwei Dinge, die sofort in den Sinn Pop:

  • Die erste ist die if ... then return else ... Paradigma zu vermeiden, da die return die else überflüssig macht.
  • Die zweite ist, den Anruf nur einmal zu tun (da es invariant ist).

diese Änderungen machen würden Sie so etwas wie:

int findMaximumValue(int list[], int first, int last) { 
    // List has one item, return it. 

    if (first == last) 
     return list[first]; 

    // Get largest of all but first element in list. 

    int maxOfAllButFirst = findMaximumValue(list, first + 1, last); 

    // First is larger than all those others, return it. 

    if (list[first] > maxOfAllButFirst) 
     return list[first]; 

    // Otherwise it's largest from the others. 

    return maxOfAllButFirst; 
} 

Ich soll jedoch erwähnen, dass Rekursion am besten für Algorithmen erfolgt, bei dem Lösungsraum schnell verringert (wie zB eine binäre Suche, wo Sie Verwerfen der Hälfte des verbleibenden Lösungsraums bei jedem rekursiven Aufruf).

Verwenden von Rekursion für etwas, wo der Lösungsraum langsam reduziert (wie diese, die im Grunde eine lineare Suche ist) ist nicht die beste Idee. Wenn die Tail-Call-Optimierung nicht möglich ist, ist der Stack-Speicherplatz wahrscheinlich nicht schnell genug.

Mit anderen Worten, der beste Weg, diesen Algorithmus eleganter zu machen, um sich aus einem rekursiven man in ein iterativen einem :-)

+0

Danke, das ist genau das, was ich gesucht habe.Das ** sonst ** ist, was ich versuchte loszuwerden! – kekstorm

+0

Und ja, diese binäre Suche vs lineare Suche ist, was ich gerade lerne Im Grunde kann man in 11 Iterationen nach dem Ziel suchen, anstatt nach 1024. Das ist nur eine einfache Zuordnung für die Art und Weise, wie linear und binär codiert wird, die Listengröße beträgt in meinem Fall nur 100, also nicht zu schlecht. – kekstorm

0

Ja, können Sie maximal von vorletztes Element berechnen, es zu einer Variablen speichern und dann verwenden:

int findMaximumValue(int list[], int first, int last) 
{ 
    if (first == last) 
     return list[first]; 
    else { 
     int maxFromSecond = findMaximumValue(list, first + 1, last); 
     if (list[first] > maxFromSecond) 
      return list[first]; 
     else 
      return maxFromSecond; 
    } 
} 

Oder eine andere Art und Weise, können Sie Funktion max(int, int) benutzen, um Ihre Funktion zu verkürzen :

int findMaximumValue(int list[], int first, int last) 
{ 
    if (first == last) 
     return list[first]; 
    else 
     return max(list[first], findMaximumValue(list, first + 1, last)); 
} 
1

Wenn Sie Funktionen zu verwenden, aus der Standard-Bibliothek erlaubt sind, können Sie die Funktion vereinfachen:

int findMaximumValue(int list[], int first, int last) 
{ 
    if (first == last) 
     return list[first]; 

    return std::max(list[first], findMaximumValue(list, first + 1, last)); 
} 

Wenn Sie nicht berechtigt sind von dem Standard-libray eine der Funktionen zu verwenden, Ihre eigene max Funktion schreiben und nutzen.

0

Dies ist eine Alternative, mit dem nächsten Aufruf = 1, liest = Anzahl der Elemente der Liste und currMax als erstes Element der Liste

int findMaximumValue(int list[], int nextIndex, int last, int currMax) 
{ 
    if (nextIndex == last) 
     return currMax; 

    int max = list[nextIndex] > currMax ? list[nextIndex] : currMax; 
    return findMax(list, ++nextIndex, last, max); 
} 
0

eleganteste Code;)

int findMaximumValue(void* list, int nextIndex, int last, int sizeofelem) 
{ 
    int result; 
    __asm { 
      push eax 
      push ecx 
      push esi 
      push edi  
      mov eax, nextIndex 
      mov ecx, eax 
      mul sizeofelem  
      mov esi, list  
      add esi, eax 
      mov edi, esi 
next:      
      cmp ecx, last 
      je stop 
comp: 
      add esi, sizeofelem 
      inc ecx 
      mov eax, [edi] 
      cmp eax, [esi]   
      jl setgrte 
      jmp next     
setgrte: 
      mov edi, esi 
      jmp next 
stop: 
      mov eax, [edi] 
      mov [result], eax 
      pop edi 
      pop esi   
      pop ecx         
      pop eax 
    } 
    return result; 
} 
//..... 
int res = findMaximumValue((void*)&arr, lov, hiv, sizeof(int)); 
0

Wie wäre es Ihrer Funktion loswerden und nur diesen Standard-Algorithmus verwenden:

std::max_element(list, list + len); 

http://www.cplusplus.com/reference/algorithm/max_element/

oder die Liste sortieren:

int myints[] = {32,71,12,45,26,80,53,33}; 
    std::vector<int> myvector (myints, myints+8);    // 32 71 12 45 26 80 53 33 

    std::sort(myvector.begin(), myvector.end(), std::greater<>()); //sort descending 

    return *(myvector.begin());