Ein Histogramm in C erstellen

BasicC

Erfahrenes Mitglied
Hi Leute ,

bin neu in der Community habe da mal eine Aufgabe komme nicht so ganz klar auf die Aufgabe.
Die Aufgabe lautet:
Schreiben Sie das Programm so um, dass ein Histogramm der eingelesenen Zahlen ausgegeben wird. Klassifizieren sie die eingelesenen Werte dazu in z. B. 25 gleich große Intervalle und geben Sie die Anzahl der in jedem Intervall gelege- nen Eingabewerte aus. Visualisieren Sie die Anzahlen zusätzlich durch '*'-Reihen pro- portionaler Länge, so dass Sie in etwa folgende Ausgabe erzeugen:


PHP:
#include <stdio.h>

#include <stdlib.h>

#include <math.h>





int main() {

   

   

    int array[10000]={0};

    int i=0, z=0, n=0;

    double avg=0,zahl,minimum,maximum;

   

   

    FILE *fp;

   

    if((fp=fopen("/Users/**********/Desktop/INF 1/A4-2_Beispieldaten/random_uniform.txt", "r"))==NULL) {

        fprintf(stderr, "Konnte Datei nicht finden\n");

        return 1;

    }

    printf("Zahlen wurden bis EOF gelesen\n");

   

    while(fscanf(fp, "%d",&array[i])==1) {

       

        if ( array[i] < 0 || array[i]  > 9999 ) {

            printf("ERR_R\n");

           

            return 1;

        }

       

        z+=array[i];

        i++;

        n++;

       

    }

    avg=(double)z/n;

   

   

    minimum=maximum=array[0];

   

    for (i=0;i<n;i++) {

        zahl=array[i];

        if (zahl<minimum) {

           

            minimum=zahl;

           

        }

        if(zahl>maximum){

           

            maximum=zahl;

           

        }

       

    }

   

    printf("Der Durchnitt ergibt: %lf\n",avg);

    printf("Minimum: %d\n", (int)minimum);

    printf("Maximum: %d\n", (int)maximum);

    printf("Anzahl n: %d\n",n);

   

    (double)n;

   

    double oben=pow(array[i]-avg,2);

    double summe=0;

    for(i=0;i<n;i++) {

        summe+=sqrt(oben/n);

       

    }

    printf("Standardabweichung: %lf\n",summe);

   

   

    return 0;

}

In der .txt Datei sind 10000 Zahlen drin.
Ich bedanke mich für jede einzelne Hilfe .
 

cwriter

Erfahrenes Mitglied
bin neu in der Community habe da mal eine Aufgabe komme nicht so ganz klar auf die Aufgabe.
Die Aufgabe lautet:
Schreiben Sie das Programm so um, dass ein Histogramm der eingelesenen Zahlen ausgegeben wird. Klassifizieren sie die eingelesenen Werte dazu in z. B. 25 gleich große Intervalle und geben Sie die Anzahl der in jedem Intervall gelege- nen Eingabewerte aus. Visualisieren Sie die Anzahlen zusätzlich durch '*'-Reihen pro- portionaler Länge, so dass Sie in etwa folgende Ausgabe erzeugen:
Was dir denn unklar?

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
@cwriter
Es hat was mit der Aufgabenstellung zutun ich habe wirklich kein Schimmer, wie ich das anstelle wie ich die for schleife setze und wie ich ikrementiere .. :/
 

cwriter

Erfahrenes Mitglied
Es hat was mit der Aufgabenstellung zutun ich habe wirklich kein Schimmer, wie ich das anstelle wie ich die for schleife setze und wie ich ikrementiere .. :/
Histogramm:

Erst sortieren (z.B. qsort), dann Klassen machen (da du min/max ja schon bestimmt hast, geht das recht einfach k = (max - min)/25 ). Dann gehst du einfach durch den Array durch, und zählst die Anzahl Elemente pro Klasse. Z.B:
C:
//Ausserhalb der main:
int sfunc(const void* a, const void* b) {
    return *(const int*)a - *(const int*)b;
}

qsort(array, 10000, sizeof(int), &sfunc);
int k = (max-min)/25;
size_t current_class = 0;

int* classarr = (int*)calloc(k, sizeof(int));
if(classarr == NULL) exit(-1);

for(size_t i = 0; i < 10000; i++)
{
    //Falls ausserhalb der Klasse: Hole die nächste Klasse
    while(array[i] > k * (current_class + 1))
        ++current_class;

    //Ansonsten sind wir in der korrekten Klasse, also Element hinzufügen
    ++(classarr[current_class]);

}

//Histogramm nun in classarr

free(classarr);

Die Ausgabe ist klar?

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
@cwriter
Also ich bedanke ich mich erstmal für deine Mühe.
Doch leider hatte ich noch nicht die variable
calloc, free, const void ,
Kann man die umschreiben ..?
Und was ist classar?
 

cwriter

Erfahrenes Mitglied
Doch leider hatte ich noch nicht die variable
Das sind Funktionen.
Das ist ein Typ.
Kann man die umschreiben ..?
Du meinst, ob es eine Alternative gibt? Auch wenn es mich in der Seele schmerzt:
C:
//Iteration über Klassen
for(size_t j = 0; j < 25; ++j)
{
    printf("\nKlasse %02d: ", j);
    int elcount = 0;
    int classmin = j * k;
    int classmax = (j+1) * k;
    //Iteration über alle (unsortierten) Elemente
    for(size_t i = 0; i < 10000; ++i)
    {
        //Wenn im Klassenbereich, zähle aktuelle Klasse hoch (und gebe Sternchen aus)
        if(array[i] >=  classmin && array[i] < classmax) {
            ++elcount;
            putc('*');
        }
    }
}
Ist allerdings O(n^2), während der vorherige Ansatz durchschnittlich O(n * log(n)) ist. Dafür ist der Speicher nur O(1) und oben O(n). Aber da du qsort nicht verwenden darfst... (Falls doch, kannst du auch erst sortieren und statt zwischenzuspeichern direkt ausgeben).

Und was ist classar?
Ein Pointer auf einen Array auf dem Heap. (Eine Variable).
Aber hattest du das noch nicht? :O

Gruss
cwriter
 

BasicC

Erfahrenes Mitglied
Super ..
Es schmerzt ich hoffe lerne es auch bald ..
Also da hätte ich noch eine Frage: Wofür steht das k ? weil das undeklariert ..
 

BasicC

Erfahrenes Mitglied
Der will da irgendwie mit putc('*') nicht arbeiten ..
Das ist die Fehleraussage :
Too few arguments to function call, expected 2, have 1