Duplikate herausfiltern
-
Hallo liebe Community!
Ich hab da mal eine Frage!
Ich hab zwei dynamische Structs! In einem sind Daten von den Mitarbeitern, ausgelesen von einer Datei! Das andere Struct besteht nur von einem Eingabe String!
Beispiele
typedef struct mitarbeiter_details { char name[20]; char vorname[20]; int alter; int gehalt[20]; char wohnort[50]; char staatsangehörigkeit[50]; char familienstand[20]; struct mitarbeiter_details *next } MITARBEITER;
typedef struct eingabe_details { char eingabestring[100]; struct eingabe_details *next; } EINGABE;
eine eingabe schaut so aus: show name, vorname, gehalt, familienstand
dieser string wird zerlegt und jedes wort wird im struct eingegeben! somit kann ich show wegstreichen!
das funktioniert ja alles; jetzt kann es ja sein das ich manche doppelt drinnen habe in meinem mitarbeiter struct! bzw das ich eine datei habe wo zwei einträge sind aber von der gleichen person aber anderer familienstand oder so!
ich will jetzt mit so einem aufruf: dub name, vorname, familienstand eines erreichen; er soll alle namen, vornamen, und familienstände untersuchen und wo alle drei gleich sind soll er es mir aus geben mit:
<vorname> / <name> (<anzahl>)
aber ich habe keinen plan wie das gehen kann; weil ich kann ja nicht drei strings miteinander verlgeichen!
Vielleicht kann mir ja jemand helfen! Leider hab ich noch nichts auser einer idee mit zwei for - schleifen!
-
...
-
das kann ich leider, nicht weil es eine "hausaufgabe" für die uni ist und diese wird auf plagiat überprüft, aber ich kann jeden den code als private nachricht schicken!
-
Du musst einfach nur deine Liste durchgehen!
Wenn vorname und Nachname übereinstimmen! Anzahlcounter erhöhen!
Dann Anzahl ausgeben!
So einfach ist das!
-
das problem ist wo mein fehler liegt:
hier das was ich schon habe! ich weiß nicht wie ich die eingabe einbauen kann damit es funktioniert, weil er soll ja nur die namen, vornamen und familienstände durchsuchen und sonst nichts!
void dub() { MITARBEITER *ptr_mitarbeiter; MITARBEITER *ptrv_mitarbeiter; int dub_counter = 1; for(ptr_mitarbeiter = first; ptr_mitarbeiter; ptr_mitarbeiter = ptr_mitarbeiter->next) { for(ptrv_mitarbeiter = ptr_mitarbeiter->next; ptrv_mitarbeiter; ptrv_mitarbeiter = ptrv_mitarbeiter->next) { if(strcmp(ptr_mitarbeiter, ptrv_mitarbeiter) == 0) { dub_counter++; } } } }
-
1. Keine Eingabe.
Du übergibst der Funktion die Daten als Parameter.2. strcmp vergleich C-Strings.
Damit kannst du keine structs vergleichen.
Zudem möchtest du ja auch zwei Strings (Name und Vorname) auf Gleichheit prüfen.3. reicht ein Schleifendurchgang aus.
Nimm dafür eine while-Schleife.**^Das ist zwar nicht zwingend notwendig, da man for- und while-Schleifen gegeneinander ersetzten kann, aber for-Schleifen nimmt man (meist), wenn man eine vorher bekannt Anzahl von Durchläufen hat.^
-
Du kannst keine ptr_mitarbeiter via strcmp vergleichen!
Spezifizier nochmal genauer, was du genau willst!
Das ist nämlich nicht so ganz klar!
-
also ich will das wenn ich dub <name>, <vorname>, <familienstand> (ohne <>) eingebe, alle doppelten einträge erscheinen und wie oft die den gleichen namen, vornamen und den gleichen familienstand haben! also alle einträge die, die drei parameter haben!
und es soll so ausgegeben werden am ende: <vorname> / <name> (<anzahl>\n
ps: ich weiß es ist sehr kompliziert, vielleicht hab ich auch nur ein gedankenfehler, aber ich komm einfach nicht drauf!
pss: es können noch mehr parameter eingeführt werden! Beispiel dub <name>, <vorname>, <alter>, <wohnort>
psss: bitte mit code schnipsel, damit ich es verstehe! wenn möglich natürlich!
-
Du gehst einfach alle Einträge durch!
Und wenn z.B. Vorname und Nachname und Familienstand gleich sind!
Gibst du sie aus!
-
Nathan schrieb:
Du gehst einfach alle Einträge durch!
Und wenn z.B. Vorname und Nachname und Familienstand gleich sind!
Gibst du sie aus!und wie vergleich ich drei strings bzw mehrere strings als zwei, ich hab keinen plan wie ich das schreiben soll?
-
Nun wenn vorname von aktuellem Mitarbeiter gleich eingegebener Vorname UND Nachname gleich eingegebem Nachnamen UND Familienstand gleich eingegebenem, dann gib ihn aus!
-
ja ok dass versteh ich!
einfach immer mit && aber ich kann ja nur zwei oder sechs parameter eingeben und das soll er erkennen und da ist glaub ich mein fail - gedanke drinnen; könntest du ein code schreiben damit ich es sehen kann, bitte!
-
Ich versteh nicht ganz worauf du hinauswillst!
-
kannst du deinen gedanken in einen code schreiben! damit ich das einmal sehen kann! bitte!
-
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...