Forum: Mikrocontroller und Digitale Elektronik größter Wert eines Array


von Gerhard H. (gerhardh)


Lesenswert?

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

von Stefan F. (Gast)


Lesenswert?

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.

von Joe F. (easylife)


Lesenswert?

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).

von MikeH (Gast)


Lesenswert?

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

von Gerhard H. (gerhardh)


Lesenswert?

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

von Joe F. (easylife)


Lesenswert?

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.

von Gerhard H. (gerhardh)


Lesenswert?

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

von Rolf M. (rmagnus)


Lesenswert?

Gerhard H. schrieb:
> tut mir leid, da ist eine Zeile untergegangen.
> Wurde editiert.

Ich glaube dir nicht, dass du das so ausgeführt hast.

von c++ (Gast)


Lesenswert?

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;

von leo (Gast)


Lesenswert?

c++ schrieb:
> Wenn anzahl gleicher Elemente immer zwei ist, gibt es was fertiges aus
> der STL:

Was haben die wohl genommen, um fuer ein Nicht-Problem eine Loesung zu 
finden.

leo

von Joe F. (easylife)


Lesenswert?

c++ schrieb:
> Wenn anzahl gleicher Elemente immer zwei ist, gibt es was fertiges aus
> der STL:

Dazu muss dann aber das Array absteigend sortiert sein. Sonst bekommst 
du den kleinsten Wert, der 2x vorhanden ist zurück.

von Rolf M. (rmagnus)


Lesenswert?

Joe F. schrieb:
> Dazu muss dann aber das Array absteigend sortiert sein.

Nein, es muss aufsteigend sortiert sein, genau wie man es in dem Code 
sieht.

von Carl D. (jcw2)


Lesenswert?

Joe F. schrieb:
> c++ schrieb:
>> Wenn anzahl gleicher Elemente immer zwei ist, gibt es was fertiges aus
>> der STL:
>
> Dazu muss dann aber das Array absteigend sortiert sein. Sonst bekommst
> du den kleinsten Wert, der 2x vorhanden ist zurück.

Container kann man auch rückwärts durchlaufen.
Beachte: rbegin()/rend()

von Rainer V. (a_zip)


Lesenswert?

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

von Joe F. (easylife)


Lesenswert?

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.

von Rofl-Tier (Gast)


Lesenswert?

Gerhard H. schrieb:
> ...
>
1
max_val = find_max_value (char feld[],  uint8_t min,  uint8_t max_val);
> ...


Kann ja nix bei rauskommen. Es wird nicht mal kompiliert. Poste doch mal 
den Code den du tatsächlich benutzt und nicht diesen Rotz.

von Rainer V. (a_zip)


Lesenswert?

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

von Joe F. (easylife)


Lesenswert?

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.)

von Rainer V. (a_zip)


Lesenswert?

OK, habs kapiert. Danke für die Erklärung!
Gruß Rainer und gute Nacht...

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.