C Code, Duplikate finden und dann alle ausgeben?

3 Antworten

Vom Beitragsersteller als hilfreich ausgezeichnet

Mach die j = i + 1 Optimierung raus und lass die Schleife auch bei 0 starten, dann klappt's wie gewünscht.
Die sorgt nämlich - was falsch ist - dafür, dass bei späteren Zahlen die vorherigen nicht mehr geprüft werden.
(Natürlich muss im if dann auch noch eine i != j Bedingung stehen, damit die Zahl sich nicht selbst als Duplikat findet)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t copy_duplicates(int dst[], const int src[], size_t len) {
    size_t n = 0;
    
    for(size_t i = 0; i < len; i++) {
      int is_duplicate = 0;
      for (size_t j = 0; j < len; j++) {
        if(src[i] == src[j] && i != j) {
          is_duplicate = 1;
          break;
        }
      }

      if (is_duplicate) {
        dst[n] = src[i];
        n++;
      }
    }
    
    return n;
}

int main (void) {
    int src[] = {5, 3, 5, 4, 4, 5};
    int len = 6;
    int dst[6];
    
    size_t num_duplicates = copy_duplicates(dst, src, len);
    
    printf("%zu\n", num_duplicates);
    
    for (size_t i = 0; i < num_duplicates; i++) {
      printf("%d ", dst[i]);
    }
    
    return EXIT_SUCCESS;
}

Pasci01  03.05.2024, 18:40

der beweis für mich, ich bin inkompetent bei der fehlersuche

MrAmazing2  03.05.2024, 18:44
@Pasci01

Ach, du hattest es doch eh fast ^^

Erste Änderung war perfekt, hätte nurnoch das "i != j" gefehlt, damit es sich nicht selbst detected, und fertig :D

Pasci01  03.05.2024, 18:47
@MrAmazing2

Wäre mir in einer testumgebung aufgefallen, ich gebe für gewöhnlich nur code raus den ich selbst testen konnte aber naja, ich bin gerade mit gefühlt 1000 anderen codes beschäftigt und nur nebenbei hier unterwegs

Was ist ein Duplikat? Dein Beispiel hat:

  • n=6 Elemente
  • u=1 Unikate (3)
  • v=3 verschiedene Elemente (5, 3, 4)
  • w=n−v=3 Wiederholungen (5: 2×, 4: 1×)
  • m=n−u=5 Mehrfachvorkommen (5: 3×, 4: 2×)

Dein Code kopiert alle Wiederholungen w (=alle Elemente, die einen identischen Nachfolger haben). Nach meinem Verständnis sind genau diese Wiederholungen die Duplikate, und Dein Beispiel {5, 3, 5, 4, 4, 5} gibt korrekt w=3 und (5, 5, 4) aus.

Offenbar willst Du aber m=5 und (5, 5, 4, 4, 5) haben. Dazu musst Du für jedes Element die ganze Liste (j=0...) durchsuchen und darfst bestenfalls bei der ersten echten Kopie (i≠j) abbrechen:

    int is_duplicate = 0;
    for (size_t j = 0; j < len; j++) {
        if( i!=j && src[i] == src[j] ) {
            is_duplicate = 1;
            break;
        }
    }

Ich würde mir diese Optimierung sparen und einfach stur zählen:

    int count = 0;
    for (size_t j = 0; j < len; j++) {
            if( src[i] == src[j]) {
                ++count;
            }
        }

Bei count==1 ist src[i] ein Unikat (u), sonst ein Mehrfaches (m). Also:

        if (count != 1) {
            dst[n] = src[i];
            n++;
        }

Dann tut das Programm so, wie Du es erwartest.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

size_t copy_duplicates(int dst[], const int src[], size_t len) {
    size_t n = 0;
    for(size_t i = 0; i < len; i++) {
        int is_duplicate = 0;
        for (size_t j = i + 1; j < len; j++) {
            if(src[i] == src[j]) {
                is_duplicate = 1;
                break;
            }
        }
        if (is_duplicate) {
            dst[n] = src[i];
            n++;
        }
    }
    return n;
}

int main (void) {
    int src[] = {5, 3, 5, 4, 4, 5};
    int len = sizeof(src) / sizeof(src[0]);
    int dst[len]; // Größe des dst-Arrays sollte der des src-Arrays entsprechen
    size_t num_duplicates = copy_duplicates(dst, src, len);

    printf("Number of Duplicates: %zu\n", num_duplicates);
    for (size_t i = 0; i < num_duplicates; i++) {
        printf("%d ", dst[i]);
    }
    printf("\n"); // Fügt einen Zeilenumbruch am Ende der Ausgabe hinzu

    return EXIT_SUCCESS;
}

Das hier sollte korrekt Funktionieren, wenn du code in Gutefrage einfügst versuche doch mal die Quelltext Funktion, dann bleibt dein code richtig formatiert :)


hitscher242 
Beitragsersteller
 03.05.2024, 18:16

danke, bekomme leider immer noch nur Number of Duplicates: 3 und 5 5 4

Pasci01  03.05.2024, 18:21
@hitscher242

Soll ich dir einen neuen code erstellen? (Ich bin gut im schreiben, weniger im korrigieren)

hitscher242 
Beitragsersteller
 03.05.2024, 18:22
@Pasci01

wäre super, aber weißt du wo mein Fehler liegt oder ist mein Code nicht dafür geeignet

Pasci01  03.05.2024, 18:24
@hitscher242

der code ist geeignet, ich bin nur gerade zu inkompetent den fehler zu sehen

hitscher242 
Beitragsersteller
 03.05.2024, 18:29
@Pasci01

wenigstens bin ich nicht ganz auf dem Holzweg, aber falls dass Angebot mit dem Code noch steht wäre ich dir äußerst dankbar. Sitze bereits seit 3 Stunden davor und finde den Fehler auch nicht

Pasci01  03.05.2024, 18:34
@hitscher242
#include <stdio.h>
#include <stdlib.h>

size_t copy_duplicates(int dst[], const int src[], size_t len) {
    size_t n = 0;
    for(size_t i = 0; i < len; i++) {
        int is_duplicate = 0;
        for (size_t j = 0; j < i; j++) { // Änderung: Suche in den bereits geprüften Elementen
            if(src[i] == src[j]) {
                is_duplicate = 1;
                break;
            }
        }
        if (!is_duplicate) {
            for (size_t k = i + 1; k < len; k++) { // Änderung: Überprüfe, ob das Element später im Array noch einmal vorkommt
                if (src[i] == src[k]) {
                    dst[n] = src[i];
                    n++;
                    break;
                }
            }
        }
    }
    return n;
}

int main (void) {
    int src[] = {5, 3, 5, 4, 4, 5};
    int len = sizeof(src) / sizeof(src[0]); // Dynamische Längenbestimmung
    int dst[len]; // Größe von dst sollte mindestens so groß wie src sein
    size_t num_duplicates = copy_duplicates(dst, src, len);

    printf("Anzahl der Duplikate: %zu\n", num_duplicates);
    printf("Duplikate: ");
    for (size_t i = 0; i < num_duplicates; i++) {
        printf("%d ", dst[i]);
    }
    printf("\n");

    return EXIT_SUCCESS;
}

Versuch mal diesen hier, ich habe bei mir leider gerade keine testumgebung

hitscher242 
Beitragsersteller
 03.05.2024, 18:39
@Pasci01

hat leider nicht funktioniert, aber danke trotzdem