größter Wert eines Array

OP #5855127
Hallo, kann mir bitte jemand sagen wo bzw was in dieser Funktion nicht 
richtig ist?


Mein Ziel ist es, den größten Wert des Array auszugeben, welcher 
mindestens 2x vorkommt.

Das Array ist bereits aufsteigend sortiert.
Habe das Programm schon bis aufs Letze gekürzt um es übersichtlich zu 
halten. Leider bekomme ich keine Ausgabe
1
uint8_t find_max_value (char feld[],  uint8_t min,  uint8_t max_val)
2
{
3
  
4
  uint8_t i, j, counter=0;
5
  
6
  for (i = 1; counter < min; i++)
7
  {
8
    counter = 0;
9
    max_val = feld[((sizeof feld)-i)];
10
    
11
    for (j=0; j < sizeof(feld); j++)
12
    {
13
      if (feld[j] == max_val)
14
      {
15
        counter++;
16
      }
17
    }
18
  }
19
  
20
  return max_val;
21
  
22
}
23

24

25

26
int main(void)
27
{
28
  char feld [] = { 1, 2, 3, 4, 5, 6, 7, 8, 8, 9};
29
    uint8_t min = 2;
30
    uint8_t max_val = 0;
31

32

33
max_val = find_max_value (char feld[],  uint8_t min,  uint8_t max_val);
34
 
35

36
 //LCD Ausgabe
37
  char row2[16];
38
  sprintf(row2, "%d",max_val);
39
  LCDWRITE(row2, 2, 1);
40
  
41
  
42
    while (1) 
43
    {
44
    }
45
}


Beste Grüße
Gast #5855132
Dein Fehler ist, dass du nicht das ganze Programm gezeigt hast. Der 
Fehler ist mit Sicherheit im nicht gezeigten Teil.

> sprintf(row2, "%d",max_val);
> LCDWRITE(row2, 2, 1);

Damit wandelst du max_val in einen String um, und gibst ihn aus. Es ist 
aber nicht erkennbar, wie die Variable deklariert ist und wie sie 
beschrieben wird. Zudem sehe ich keinen Aufruf deiner Funktion 
find_max_value(), die inhaltlich noch nicht geprüft habe.
#5855135
sizeof(feld) liefert dir nur innerhalb von main() die Anzahl der 
Elemente zurück.
An find_max_value() übergibst du einen Pointer auf das erste Element des 
Arrays.
Du könntest es auch so schreiben, dann wäre es klarer was passiert:

uint8_t find_max_value (char *feld,  uint8_t min,  uint8_t max_val)

Innerhalb von find_max_value() liefert dir sizeof(feld) die Größe des 
Pointers (4 Bytes vermutlich).
Gast #5855139
Wenn das Array schon aufsteigend sortiert ist, dann iterierst du von 
hinten solange bis zwei Elemente gleich sind


int i, max;
for(i = sizeof(feld)-2; i >= 0 && (feld[i+1] != feld[i]); --i);

if(i >= 0)
   max = feld[i];
OP #5855142
Stefanus F. schrieb:
> Dein Fehler ist, dass du nicht das ganze Programm gezeigt hast. Der
> Fehler ist mit Sicherheit im nicht gezeigten Teil.
>
>> sprintf(row2, "%d",max_val);
>> LCDWRITE(row2, 2, 1);
>
> Damit wandelst du max_val in einen String um, und gibst ihn aus. Es ist
> aber nicht erkennbar, wie die Variable deklariert ist und wie sie
> beschrieben wird. Zudem sehe ich keinen Aufruf deiner Funktion
> find_max_value(), die inhaltlich noch nicht geprüft habe.


tut mir leid, da ist eine Zeile untergegangen.
Wurde editiert.

Beste Grüße
#5855145
Du solltest unbedingt auch den Fall behandeln, dass in deinem Array kein 
Wert 2x vorkommt...

Vorschlag:
1
int find_max_value (char feld[], uint8_t elements, uint8_t min_occurences)
2
{
3
  int i, j, cnt;
4

5
  for (i=(elements-1); i>=0; i--)
6
  {
7
    cnt = 1;
8
    for (j=(i-1); j>=0 ; j--)
9
    {
10
      if (feld[i] == feld[j])
11
        cnt++;
12
      else
13
        break;
14
    }
15
    if (cnt >= min_occurences)
16
      return (feld[i]);
17
  }
18
  
19
  return -1;
20
}
21

22

23
(...)
24

25
val = find_max_value(feld, sizeof(feld), 2);

liefert -1 zurück, wenn kein Wert ausreichend oft gefunden wurde.
OP #5855195
Joe F. schrieb:
> Du solltest unbedingt auch den Fall behandeln, dass in deinem Array kein
> Wert 2x vorkommt...
>
> Vorschlag:
>
>
1
> int find_max_value (char feld[], uint8_t elements, uint8_t 
2
> min_occurences)
3
> {
4
>   int i, j, cnt;
5
> 
6
>   for (i=(elements-1); i>=0; i--)
7
>   {
8
>     cnt = 1;
9
>     for (j=(i-1); j>=0 ; j--)
10
>     {
11
>       if (feld[i] == feld[j])
12
>         cnt++;
13
>       else
14
>         break;
15
>     }
16
>     if (cnt >= min_occurences)
17
>       return (feld[i]);
18
>   }
19
> 
20
>   return -1;
21
> }
22
> 
23
> 
24
> (...)
25
> 
26
> val = find_max_value(feld, sizeof(feld), 2);
27
> 
28
>
>
> liefert -1 zurück, wenn kein Wert ausreichend oft gefunden wurde.



Oh, danke für den Hinweis. Diesen Fall hatte ich tatsächlich nicht 
berücksichtigt.

DANKE vielmals an ALLE!
Schönes Wochenende
Gast #5855408
MikeH schrieb:
> Wenn das Array schon aufsteigend sortiert ist, dann iterierst du von
> hinten solange bis zwei Elemente gleich sind
>
>
> int i, max;
> for(i = sizeof(feld)-2; i >= 0 && (feld[i+1] != feld[i]); --i);
>
> if(i >= 0)
>    max = feld[i];

Wenn anzahl gleicher Elemente immer zwei ist, gibt es was fertiges aus 
der STL:
1
int array[] = {1,3,5,6,7,9,10,10,12};
2
auto resultIt = std::adjacent_find(std::rbegin(array), std::rend(array));
3
if (resultIt == std::rend(array)) {
4
  //no element found
5
}
6
int resultValue = *resultIt;
#5856048
Also rein logisch betrachtet, mußt du doch nur jedes Element im Array 
mit allen anderen vergleichen. Da ist es egal, ob das Array sortiert ist 
und es ist egal, ob du "vorn" oder "hinten" anfängst. Wenn sicher ist, 
dass es nur ein Paar im Array geben kann, dann liefert die Suche 
entweder "kein Paar" oder das Paar. Wenn es mehrere Paare geben kann, 
kommen alle Paare als Suchergebnis. Prinzipiell liefert so eine Funktion 
natürlich beliebig lange Tupel, also nicht nur Paare. Das alles läuft in 
zwei verschachtelten Schleifen ab, in denen du die verschiedenen, 
möglichen Ergebnisse verarbeitest.
Da ich außer Python keine Hochsprache wirklich beherrsche, verkneife ich 
mir einen Beispielcode :-)
Gruß Rainer
#5856223
Rainer V. schrieb:
> Also rein logisch betrachtet, mußt du doch nur jedes Element im Array
> mit allen anderen vergleichen. Da ist es egal, ob das Array sortiert ist

Mit der Größe des Arrays steigt der Aufwand bei dieser Methode aber 
exponentiell.
Gute Sortieralgorithmen leisten da schon mal eine effiziente Vorarbeit.
Wenn man sich nach dem Sortieren von der größten Zahl nach "vorne" 
durcharbeitet, ist die Wahrscheinlichkeit recht hoch, hier nicht mehr 
lange suchen zu müssen.
#5856254
Joe F. schrieb:
> Mit der Größe des Arrays steigt der Aufwand bei dieser Methode aber
> exponentiell.

Du hast natürlich recht, aber in diesem Fall hier, sehe ich keinen 
Vorteil einer Sortierung. Du mußt doch immer noch jede Zahl des Arrays 
mit allen anderen vergleichen oder?! Natürlich kann es "Rand"bedingungen 
zum Aufbau des Arrays geben, die eine andere Suche sinnvoller als das 
komplette Vergleichen machen. Jedenfalls war die Angabe zum Array 
lediglich, dass Zahlen mindestens doppelt vorkommen können und damit 
macht das Vorsortieren keinen Sinn mehr...du mußt jede Zahl des Arrays 
mit allen anderen vergleichen. Oder habe ich gerade einen Knoten im Kopf 
:-)
Gruß Rainer
#5856324
Rainer V. schrieb:
> Du mußt doch immer noch jede Zahl des Arrays
> mit allen anderen vergleichen oder?!

Nein. Sortieralgorithmen versuchen genau dies zu verhindern, da der 
Aufwand exponentiell steigen würde.
Bei dem Beispiel hier mit nur 10 Array-Elementen spielt das keine Rolle, 
aber lass es mal tausende von Werten werden.
Nach dem Sortieren beschränkt sich das Vergleichen auf die Anzahl der 
Elemente im Array, da immer nur mit den direkten Nachbarn verglichen 
werden muss (der Aufwand steigt dann also nur linear mit der Anzahl der 
Array-Elemente).

Wenn sich der Wertebereich im Array auf char beschränkt, gäbe es noch 
eine sehr schnelle, aber etwas speicherintensivere Lösung:
Man nimmt ein Hilfsarray mit 256 Einträgen, und inkrementiert den Wert 
in diesem Hilfsarray jedesmal bei dem Index, der dem Wert im 
(unsortierten) Daten-Array entspricht.
Für jeden theoretisch im Daten-Array vorkommenden Wert steht im 
Hilfsarray dann die Anzahl der gefundenen Werte.
Anschließend durchsucht man dieses Hilfsarray von hinten anfangend 
(Wert=255) nach unten, bis das Suchkriterium (Mindestanzahl der 
Vorkommnisse) erfüllt ist.
Der Rechenaufwand ist entsprechend gering und steigt quasi linear mit 
der Größe des zu durchsuchenden Arrays:
Anzahl der Elemente im Daten-Array + 255 (max.)

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 7 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.