Duplikate herausfiltern
-
Pseudocode!
void dub(char vorname, char nachname, char familienstand) { for (each in mitarbeiter) if (mitarbeiter->vorname == vorname && mitarbeiter->nachname == nachname && mitarbeiter->familienstand == familienstand) print(mitarbeiter); }
-
so und was ist jetzt wenn ich nicht familienstand sonder name, vorname und alter untersuchen will? bei dir jetzt funktioniert es ja nur mit name, vorname und familienstand? ich kann alles was im struct von den mitarbeitern steht untersuchen und so viele parameter eingeben wie ich einträge im struct habe! also es muss alles dynamisch sein und hier steig ich aus!
-
OK, in C wird das tricky, da ich jetzt virtuelle Funktionen nachbilden muss.*
Folgende struct:typedef struct member_comparer_detail { void *data; // die Daten die verglichen werden int is_used; // ob die verglichen werden müssen int (*compare_member)(struct member_comparer_detail*, MITARBEITER *); // die "virtuelle" Vergleichsfunktion } member_comparer;
Du brauchst nun für jeden Member eine Funktion in der Art:
int comparer_alter(member_comparer *this, MITARBEITER *worker) { if (!this->is_used) // wenn der Parameter nicht vom User eingegeben wurde return 1; // alle sind in Ordnung if (*(int*)this->data == worker->alter) return 1; // alter stimmt überein return 0; // keine Übereinstimmung } int comparer_vorname(member_comparer *this, MITARBEITER *worker) { if (!this->is_used) // wenn der Parameter nicht vom User eingegeben wurde return 1; // alle sind in Ordnung if (strcmp((char*)this->data, worker->vorname) == 0) return 1; // vorname stimmt überein return 0; // keine Übereinstimmung }
Desweiteren brauchst du noch ein Array von member_comparern, was groß genug ist um jeden Member aufzunehmen (Am besten ein enum für einfachen Zugriff definieren).
Der User muss dann so etwas eingeben wie:
dub NAME=<name> ALTER=<alter>
Dass ist notwendig, da man irgendeine Zuordnung der Werte hinter dub braucht.
Beim parsen erstellst du dir entsprechende member_comparer:// wenn Alter vom User gefiltert werden soll member_comparer_array[MEMBER_ALTER].is_used = 1; member_comparer_array[MEMBER_ALTER].data = malloc(sizeof(int)); *(int*)member_comparer_array[MEMBER_ALTER].data = vomNutzerEingegebenesAlter; member_comparer_array[MEMBER_ALTER].compare_member = comparer_alter; // Ansonsten member_comparer_array[MEMBER_ALTER].is_used = 0; member_comparer_array[MEMBER_ALTER].data = NULL; member_comparer_array[MEMBER_ALTER].compare_member = comparer_alter; // usw für jeden Member
Die dup-Funktion sieht dann wie folgt aus (wieder Pseudocode):
void dup(member_comparer *arr) { for (each mitarbeiter) { int is_filtered = 1; // Anfangs stimmt der Mitarbeiter for (each member_comparer) if (!member_comparer.compare_member(member_comparer, mitarbeiter)) // wenn luat member_comparer nicht passt { is_filtered = 0; // als nicht gefiltert markieren und raus break; } if (is_filtered) // wenn gefiltert werden soll print(mitarbeiter); // ausgeben } }
Am Ende nicht vergessen den mit malloc angeforderten Speicher wieder freizugeben!
*Und langsam wird mir das mit den ! auch zu blöd, da dus noch nicht mal bemerkst wie dämlich das ist, wenn ! am Ende von JEDEM Satz sind.
-
Versuch doch erstmal nur die beiden Namen zu vergleichen.
Danach kannst du weitermachen.Danach kannst du dir ja eien Referenz-struct füllen, mit ungültigen Werten an den Stellen, die du nicht vergleichen willst. (Z.B. Alter = -1, Name = "")
Dann zählst du, wieviel Einträge übereinstimmen.void dub(struct *referenz, int anzahl) { int anz; for (each in mitarbeiter) anz = 0; if ((referenz->vorname != "") && (mitarbeiter->vorname == referenz->vorname)) anz ++; if ((referenz->nachname != "") && (mitarbeiter->nachname == referenz->nachname )) anz ++; if ((referenz->alter >= 0) && (mitarbeiter->alter == referenz->alter )) anz ++; ... if (anz == anzahl) print(mitarbeiter); }
Stringvergleich funktioniert in C anders.
-
ich danke dir für die hilfe mit den codes. werde es mir ansehen und einbauen.
und wegen den "!", ich mag die einfach lieber als die punkte. keine ahnung wieso.
-
DirkB schrieb:
Danach kannst du dir ja eien Referenz-struct füllen, mit ungültigen Werten an den Stellen, die du nicht vergleichen willst. (Z.B. Alter = -1, Name = "")
Dann zählst du, wieviel Einträge übereinstimmen.Wieso einfach, wenns auch kompliziert geht?
Auf die einfache Idee einfach ungültige Werte zu nehmen kam ich nicht...
-
Jetzt muss man nur noch geeignete ungültige Werte finden.
@Heinzi: Warum ist dein Eintrag für Gehalt ein int-Array?
Und für Familienstand bietet sich ein enum an.
-
sorry hab mich verschrieben, hab es nicht kopiert, sondern gleich so geschrieben und mit dem enum hab ich mich noch nie so richtig befasst.
-
Dann wäre jetzt die Gelegenheit dafür.
enum Familienstand {ungueltig, ledig, geschieden, verwitwet, familienstand_ende}; typedef struct mitarbeiter_details { ... Familienstand familienstand; ... } MITARBEITER;
Die Bezeicher des enum sind nur Namen für int-Werte.
In diesem Beispiel wäre ungueltig 0, ledig 1, usw
-
also ein freund von mir hat mir gesagt man kann das auch so machen.
1. man durchloopt das struct und erzeugt auf jedes element einen pointer
2. beim ersten element beginnnend alle relevanten attribute abfragen
3. jedes element mit allen anderen einträgen im array abfragen
4. wenn eines matcht dann löscht man den pointer aus dem array von dem matchenden
5. und machen das fürs nächste noch nicht gelöschte element im array
so meine frage ist, wie kann man dieses schritte programmieren. bitte um hilfe
neues struct würde so aussehen:
struct relevant {
* array [ ]
}