Rangliste erstellen

Hallo,

Ich habe in meinen Programm mehrere Zähler so um die 20 Stück (Integer). Jetzt würde ich gerne eine automatische Rangliste erstellen lassen und dies dann auf mein HMI ausgeben.

Meine Frage ist wie ich dies einfach programmieren könnte das es mir automatisch z.B. meine Zähler auswertet und die ersten 5 Zähler (die Zähler die am höchsten sind) dann in den Variable für das HMI schreibt zum Anzeigen.

Das mit dem HMI anzeigen ist kein Problem nur eben wie ich alle Zähler miteinander vergleichen kann und eine Rangfolge erstellt wird.

Mit freundlichen Grüßen Andre :slight_smile:

Die Werte in einem Array halten und sortieren.

Da wirst du massig Suchergebnisse finden. BubbleSort, Quicksort,...

Am einfachsten, wenn alle Zähler (können die negativ werden - wegen int?) in einem Array stehen. Mehr kann man ohne Deinen Sketch dazu nicht konkretisieren.

Gruß Tommy

Bedenke, dass du in Wirklichkeit nicht nur Zahlen sortieren willst, sondern zum Zähler wohl auch Zusatzinformation gehört (Bei einer HiScore-Tabelle z.B. der Name).

Wirst also eher Zeiger umsortieren, oder eine sortierte Kette der Elemente aufbauen.

Und da hast du die Wahl, diese Zeiger bei jeder Änderung eines Zählers zu aktualisieren oder einmal gezielt alle Zeiger neu aufzubauen.

Danke
Array war das Stichwort.
Meine Zähler sind nur positiv.

Hab ein kleines Beispiel Skript geschrieben wo ich 5 Zähler sortieren lasse und mir im Serial Monitor Ausgebe.

Meine Frage zu diesen Sketch ist,

Ich gebe im Serial Monitor aus.

Unsortiert Array: 372,200,439,6,692
Sortiert Array:6,200,372,439,692
Nummer 1: 692
Nummer 2: 439
Nummer 3: 372

Wie kann ich es Programmieren das mir anstatt das Ergebnis der Name vom Int ausgeben wird ? z.B Nummer 1: Z5

Programm:

int Z1 =372;
int Z2 =200;
int Z3 =439;
int Z4 = 6;
int Z5 = 692;
const int iaSize = 5;    //Array size
int sortValues[iaSize] = {Z1, Z2, Z3, Z4, Z5,};

void printarray(){      //Print array to Com3
for (int i=0; i<iaSize; i++) {    //loop through array
Serial.print (sortValues [i]);    //Print value indexed by i
if(i<(iaSize-1)){Serial.print(',');}  //Separator
}
Serial.println();       //Blank line
}

 void sort(int ia[], int size){     //Sort Routine int

for (int x = 0; x < iaSize; x++){   //Outer loop
for(int y = 0; y < iaSize-1; y++){ //Inner loop
if(ia[y] > ia[y+1]){                //if this value is bigger than next
int tmp = ia[y+1];              //Store a temp of the next
ia[y+1] = ia[y];          //Move this value to next position in array
ia[y] = tmp;}           //Put temp value at the current position
 }
}
}
 void setup(){        //Do this 1 time in the setup routine
 
 Serial.begin (9600);     
Serial.print ("Unsortiert Array: "); 
printarray();      
sort (sortValues, iaSize);    
Serial.print("Sortiert Array:");    
printarray(); 
Serial.print("Nummer 1: ");        
Serial.print (sortValues [4]); 
Serial.println();
Serial.print("Nummer 2: ");       
Serial.print (sortValues [3]); 
Serial.println();
Serial.print("Nummer 3: ");        
Serial.print (sortValues [2]); 

 }

 void loop() {}
//Put your code here

Den Variablen Namen kannst du dir nicht ausgeben lassen. Diese werden vom Kompiler entfernt. Diese dienen nur zur Lesbarkeit des Menschen.

Du könntest dir auch ein struct anlegen, und jedem Wert einen zugehörigen Namen geben.

1 Like

Hier mal eine Demo für eine Kette von Elementen, die neben Name und Zählerstand auch einen Zeiger auf das nächst kleinere Element haben. Viel Spaß.

class HiScore : public Printable {
   const char* name;
   unsigned int score; 
   HiScore* _next;
   static HiScore* _top;
public:
    HiScore(const char* name): name(name), score(0), _next(nullptr) {} 
    
    void ausketten() {
       HiScore* p = _top;
       if (this == _top) {_top = _next; return;}
       HiScore* n = p->_next;
       while (n != this) {
         if (n == nullptr) return;
         p = n; 
         n = p->_next;
       }
       p->_next = _next;
    }
    
    void set (unsigned int _score) {
       score = _score;
       // sortiert Element in die Kette ein
       if (_top == nullptr) {_top = this; return;}

       ausketten();

       HiScore* p = _top;
       if (p->score < score) {
           //  Bei top einhängen
           _top = this; 
           _next = p;
           return;
       }
       HiScore* n = p->_next;
       while(n && n->score > score) {
           p = n; 
           n = p->_next; // loop
       }   
       // Hier einhängen
         p->_next = this; 
         _next = n;
  }

    
    HiScore* next() {return _next;}

    static HiScore* top() {return _top;}

    size_t printTo(Print& p) const{
      size_t len = p.print(name);
      len += 1; p.write(':');
      len += p.print(score);
      if (_next) { len+=p.print("->"); len+= p.print(_next->name); }
      return len;
    }  
};

HiScore* HiScore::_top=nullptr;  // staatische Variable: Kettenanker

HiScore M("Michael");
HiScore T("Tommy");
HiScore A("Andre");


void setup() {
  Serial.begin(115200); 
  Serial.println("HiScore Demo");
  M.set(100);
  T.set(90);
  A.set(160);
}

void loop() {
Serial.println("-----");
  HiScore* h = HiScore::top();
  while (h) {
    Serial.println(*h);
    h = h->next();
  }
while (! Serial.available()) { }  

  char c = Serial.read();  // erwartet "A999" o.ä.
  int score = Serial.parseInt();  
  switch(c) {
    case 'A': A.set(score); break;
    case 'T': T.set(score); break;  
    case 'M': M.set(score); break;  
    default: Serial.println(" ? ? "); break;
  }
  while (Serial.available()) {Serial.read(); delay(1); } 
}

Fehlt noch, die Daten im EEPROM zu speichern oder so, und neue Elemente zu erzeugen...

Danke,
Werde ich mir heute Abend genauer anschauen. :+1:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.