C: Array mit zufälligen Zahlen füllen und sortieren

Schnelle objektorientierte, kompilierende Programmiersprache.
Antworten
Lone
Beiträge: 26
Registriert: Do Sep 19, 2013 2:38 pm

C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von Lone » Di Sep 24, 2013 11:06 pm

Hey,
hab ein neues Problem. Ich wollte ein Programm mit 2 Funktionen schreiben. Die 1. füllt ein Feld mit zufälligen Zahlen und die 2. soll diese dann sortieren.
Ich hab wahrscheinlich eine Menge Fehler gemacht und komme von selber nicht weiter.
Vielleicht kann mir jemadn zeigen wo die Fehler sind und/oder ob es eine bessere Schreibweise gibt.

Eigentlich war es geplant das die Funktion ErzeugtFeld eine vom Benutzer festgelegte Anzahl an Feldern erstellt aber da wusste ich dann nicht wie man Felder mit einer Funktion erzeugt.

Code: Alles auswählen

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

int ErzeugtFeld();
int EinfSort();

//Hauptprogramm
main() {
	int feld1[255],feld2[255];

	feld1[255]=ErzeugtFeld();
	printf("%i\n",feld1);
	feld2[255]=ErzeugtFeld();
	printf("%i\n",feld2);
	
	feld1[255]=EinfSort(feld1,50);
	feld2[255]=EinfSort(feld2,50);
	printf("%i\n",feld1);
	printf("%i\n",feld2);

	printf("\n\n");
	system("PAUSE");
	return 0;
}

//Funktion erzeugt Felder mit zufälligen Ganzzahlen.
int ErzeugtFeld() {
	int zaehler,x;
	int feld[255];
	time_t t;

	time(&t);
	srand((unsigned)time(&t));

		for(zaehler=0; zaehler<50;zaehler++) {
			x=rand()%50;
			feld[zaehler]=x;
		}
	}

//Funktion sortiert die Zahlen in den Feldern
int EinfSort (int a[],int anzahl) {
	int x,i,j;

	for(i=1; i<anzahl; i++) {
		x=a[i];
		j=i-1;
		while((x<a[i]) && (j>=0)) {
			a[j+1] =a[j];
			j--;
		}
		a[j+1]=x;
	}
}
MfG Lone

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von nufan » Mi Sep 25, 2013 12:55 am

Tag :)

Da sind ein paar ziemlich grundsätzliche Fehler drin. Ich packe gleich ein paar Links zum Wiki dazu.
Lone hat geschrieben:Eigentlich war es geplant das die Funktion ErzeugtFeld eine vom Benutzer festgelegte Anzahl an Feldern erstellt aber da wusste ich dann nicht wie man Felder mit einer Funktion erzeugt.
Was verstehst du unter "Fehler erzeugen/erstellen"? Ein Feld mit Werten füllen? Speicher dafür reservieren?

http://www.proggen.org/doku.php?id=c:tutorial:arrays
http://www.proggen.org/doku.php?id=c:tutorial:memory
Lone hat geschrieben:

Code: Alles auswählen

int EinfSort();
...
int EinfSort (int a[],int anzahl)
Die Signatur des Prototyps sollte mit der tatsächlichen Signatur der Funktion übereinstimmen (auch wenn das der Compiler möglicherweise auch so akzeptiert). Das ist hier nicht der Fall.

http://www.proggen.org/doku.php?id=c:tutorial:functions
Lone hat geschrieben:

Code: Alles auswählen

main()
"main" sollte die Signatur

Code: Alles auswählen

int main()
bzw.

Code: Alles auswählen

int main( int argc, char *argv[] )
haben. *

http://www.proggen.org/doku.php?id=c:tutorial:params

(Der Rest zu "main" kommt zum Schluss)
Lone hat geschrieben:

Code: Alles auswählen

int ErzeugtFeld() {
    int zaehler,x;
    int feld[255];
    time_t t;

    time(&t);
    srand((unsigned)time(&t));

      for(zaehler=0; zaehler<50;zaehler++) {
          x=rand()%50;
          feld[zaehler]=x;
      }
}
Du legst ein Feld innerhalb der Funktion an und füllst es mit Zufallswerten. Danach wird das Feld zerstört und die Ausführung geht in der aufrufenden Funktion (in diesem Fall "main") weiter.
Warum überhaupt "int" als Rückgabewert? Was willst du zurückgeben? Wenn du einen Rückgabewert von "int" hast, dann solltest du mittels "return" einen Integer zurückgeben, ansonsten wäre der Rückgabetyp "void" ("nichts") angebracht.
Lone hat geschrieben:

Code: Alles auswählen

int EinfSort (int a[],int anzahl) {
    int x,i,j;

    for(i=1; i<anzahl; i++) {
      x=a[i];
      j=i-1;
      while((x<a[i]) && (j>=0)) {
          a[j+1] =a[j];
          j--;
      }
      a[j+1]=x;
    }
}
Hm... sieht mir nach einer falschen Implementierung von Insertionsort aus. Da ist ein Fehler drin, denk dir das bitte nochmal genau durch.
Und wieder: Warum ein Rückgabetyp "int"?

(Leider noch kein Artikel im proggen.org-Wiki :()
http://de.wikipedia.org/wiki/Insertion_sort

Lone hat geschrieben:

Code: Alles auswählen

main() {
    int feld1[255],feld2[255];

    feld1[255]=ErzeugtFeld();
    printf("%i\n",feld1);
    feld2[255]=ErzeugtFeld();
    printf("%i\n",feld2);
    
    feld1[255]=EinfSort(feld1,50);
    feld2[255]=EinfSort(feld2,50);
    printf("%i\n",feld1);
    printf("%i\n",feld2);

    printf("\n\n");
    system("PAUSE");
    return 0;
}
Die Zuweisungen der Funktions-Rückgaben ignoriere ich jetzt mal, bitte schau dir die verlinkten Artikel zu Arrays und Funktionen/Rückgabewerten an.
Was versuchst du mit den "printf()" auszugeben?
"system()" ist sehr schlechter Stil und sollte vermieden werden. Wenn du verhindern willst, dass dein Programm sich einfach wieder beendet gibt es dafür andere Möglichkeiten:
http://www.proggen.org/doku.php?id=c:fa ... disappears


* Der Vollständigkeit halber:

Code: Alles auswählen

int main( int argc, char *argv[], char *envp[] )
ist ebenfalls möglich, alles andere ist systemspezifisch.

Lone
Beiträge: 26
Registriert: Do Sep 19, 2013 2:38 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von Lone » Mi Sep 25, 2013 12:53 pm

Danke für die Antwort. Gestern habe ich da nurnoch experimentiert, weil nichts funktionierte und irgendwann hatte ich keinen Durchblick mehr.

Ich hab jetzt nochmal komplett neu angefangen. Ich räum erstmal bei den Funktionen auf und versuch das ganze mit Pointern. Im Hauptprogramm soll das Feld befüllt,ausgedruckt,sortiert und nochmal ausgedruckt werden.

Als erstes eine Funktion die Felder mit zufälligen Zahlen befüllt.
Ich habe Testweise 1 Reihe und 5 Spalten genommen.

Code: Alles auswählen

void FuelleFeld (int *x,int reihen, int spalten) {          //1 Reihe , 5 Spalten
	int i, j;

    srand(time(NULL));
	for(i=0; i<reihen; i++) {
		for(j=0; j<spalten; j++) {
		*(x+(i*spalten)+j) = rand() % 20;
		}
	}
}
Die andere Funktion hat auch funktioniert aber so finde ich das übersichtlicher.

Die Funktion zum drucken.

Code: Alles auswählen

void DruckeFeld(int *x, int reihen, int spalten) {
	int i, j;
	printf("\n\n");
	for(i=0; i<reihen; i++) {
		for(j=0; j<spalten; j++) {
			printf(" %d",*(x+(i*spalten)+j));  //printf(" %d",a[0 1 2 3 4])
		}
		printf("\n");
	}
}
Dann habe ich im Internet ein wenig nach Sortierverfahren gesucht, weil ich von selber einfach nicht drauf gekommen bin. Das ganze ist in 2 Funktionen unterteilt. Hier brauche ich ein wenig Erklärungshilfe. Ich schreibe daneben wie ich es interpretiert habe.

Code: Alles auswählen

void FeldSort(int *x, int size) {                                       //Zeiger auf int-Feld, Groesse des Feldes = 5
	int i, temp, minIndex;                                     
	for(i=0; i<size-1; i++) {                                    //läuft 4 mal (i=0; 0<4;i++)
		minIndex = FeldMinIndex(x, i, size);  //beim ersten Durchlauf (x, 0, 4)
		if(i != minIndex) {                             //
			temp = x[i];
			x[i] = x[minIndex];
			x[minIndex] = temp;
			}
	}
}

int FeldMinIndex(int *x, int start, int size) {                   //(x, 0, 4)
	int minIndex=start, i;                                     //minIndex=0
	for(i=start; i<size; i++) {                                //(i=0; 0<4;0=0+1)
		if(x[i] < x[minIndex]) {                    //hier komme ich nicht weiter. wenn x[i=0] < x[0] ???
			minIndex = i;                 
		}
	}
	return minIndex;
Und hier main.

Code: Alles auswählen

int  main() {
	int a[5];
	FuelleFeld(&a[0], 1, 5);
	DruckeFeld(&a[0], 1, 5);
	FeldSort(&a[0], 5);
	DruckeFeld(&a[0], 1, 5);

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von nufan » Mi Sep 25, 2013 2:00 pm

Lone hat geschrieben:Als erstes eine Funktion die Felder mit zufälligen Zahlen befüllt.
Sieht doch schon besser aus :)
Lone hat geschrieben:Die andere Funktion hat auch funktioniert aber so finde ich das übersichtlicher.
Sei mir nicht böse, aber das kann ich dir so leider nicht glauben ;)
Lone hat geschrieben:Dann habe ich im Internet ein wenig nach Sortierverfahren gesucht, weil ich von selber einfach nicht drauf gekommen bin. Das ganze ist in 2 Funktionen unterteilt. Hier brauche ich ein wenig Erklärungshilfe. Ich schreibe daneben wie ich es interpretiert habe.
Das ist ein Selectionsort. Am bestehen helfen Animation um das besser zu verstehen:
http://www.youtube.com/watch?v=EdUWyka7kpI
Und auch hier noch eine Erklärung:
http://www.proggen.org/doku.php?id=algo:selectionsort

Lone
Beiträge: 26
Registriert: Do Sep 19, 2013 2:38 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von Lone » Mi Sep 25, 2013 3:23 pm

Sei mir nicht böse, aber das kann ich dir so leider nicht glauben
Funktioniert doch ?

Code: Alles auswählen

main() {
int zaehler,wert,feld[80];
time_t t;

   time(&t);
   srand((unsigned)time(&t));

      for(zaehler=0; zaehler<20;zaehler++) {
         wert=rand()%20;
		 printf("%i\n",wert);
         feld[zaehler]=wert;
	  }
	  return 0;
   }
Ich glaube ich habs gerade kapiert. Dieser Ausschnitt hat mich verwirrt:#

Code: Alles auswählen

 if(x[i] < x[minIndex])
Ich hab total vergessen das mit x[0] die zufällige Zahl die an Stelle 0 steht überprüft wird. Hoffe ich zumindest.

Das ist garnicht so einfach aber die praktischen übungen helfen doch mehr als nur zu lesen was der Code tut.

Lone
Beiträge: 26
Registriert: Do Sep 19, 2013 2:38 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von Lone » Mi Sep 25, 2013 6:07 pm

Mir ist aufgefallen das das Programm immer wieder die gleichen Zahlen in ein Feld schreibt, wenn ich ein weiteres hinzufüge. Sollte rand nicht dafür sorgen das immer wieder zufällige Zahlen eingefügt werden?

Hier nochmal der ganze Code:

Code: Alles auswählen

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

void FeldSort(int *x, int size) {                                    
   int i, temp, minIndex;                                     
   for(i=0; i<size-1; i++) {                                   
      minIndex = FeldMinIndex(x, i, size);  
      if(i != minIndex) {                            
         temp = x[i];
         x[i] = x[minIndex];
         x[minIndex] = temp;
         }
   }
}

int FeldMinIndex(int *x, int start, int size) {
   int minIndex=start, i;
   for(i=start; i<size; i++) {
      if(x[i] < x[minIndex]) {
         minIndex = i;                 
      }
   }
   return minIndex;
}

void DruckeFeld(int *x, int reihen, int spalten) {
   int i, j;
   printf("\n\n");
   for(i=0; i<reihen; i++) {
      for(j=0; j<spalten; j++) {
         printf(" %d",*(x+(i*spalten)+j));
      }
      printf("\n");
   }
}

void FuelleFeld (int *x,int reihen, int spalten) {
   int i, j;

    srand(time(NULL));
   for(i=0; i<reihen; i++) {
      for(j=0; j<spalten; j++) {
      *(x+(i*spalten)+j) = rand() % 20;
      }
   }
}

int  main() {
	int a[5],a1[5];

	FuelleFeld(&a[0],1,5);
	DruckeFeld(&a[0],1,5);
	FeldSort(&a[0],5);
	DruckeFeld(&a[0],1,5);

	FuelleFeld(&a1[0],1,5);
	DruckeFeld(&a1[0],1,5);
	FeldSort(&a1[0],5);
	DruckeFeld(&a1[0],1,5);
	
	printf("\n\n");
	system("PAUSE");
	return 0;
}

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von nufan » Mi Sep 25, 2013 9:17 pm

Lone hat geschrieben:
Sei mir nicht böse, aber das kann ich dir so leider nicht glauben
Funktioniert doch ?
Jetzt ja - meine Aussage war auf den alten Code bezogen.
Lone hat geschrieben:Mir ist aufgefallen das das Programm immer wieder die gleichen Zahlen in ein Feld schreibt, wenn ich ein weiteres hinzufüge. Sollte rand nicht dafür sorgen das immer wieder zufällige Zahlen eingefügt werden?
Das hat einen einfachen aber zugegeben nicht ganz offensichtlichen Grund.

Versuch mal diese Funktion:

Code: Alles auswählen

    void FuelleFeld (int *x,int reihen, int spalten) {
       int i, j;
       unsigned int seed = time(NULL);
       printf("seed: %u\n", seed);
       srand(seed);
       for(i=0; i<reihen; i++) {
          for(j=0; j<spalten; j++) {
          *(x+(i*spalten)+j) = rand() % 20;
          }
       }
    }
Meine Ausgabe:

Code: Alles auswählen

seed: 1380139943


 16 14 4 15 10


 4 10 14 15 16
seed: 1380139943


 16 14 4 15 10


 4 10 14 15 16
Dein Programm bekommt von time(NULL) zwei mal den gleichen Wert, weil es zu schnell durchläuft.
Nun musst du dir im klaren sein wie srand() bzw. rand() arbeiten. Von einem Ausgangswert (seed) wird durch Berechnungen - eindeutige, wiederholbare Berechnungen - der Zustand des Generators verändert und Werte generiert. Nimmst du zwei mal den gleichen Seed, wirst du beide Male die gleiche Zustandsabfolge und infolgedessen gleiche Zufallszahlen bekommen. Das Problem kannst du einfach lösen indem du srand() nur ein einziges mal aufrufst, am besten am Anfang von main().

Lone
Beiträge: 26
Registriert: Do Sep 19, 2013 2:38 pm

Re: C: Array mit zufälligen Zahlen füllen und sortieren

Beitrag von Lone » Do Sep 26, 2013 9:35 am

Vielen Dank!

Jetzt klappt alles so wie ich möchte. :)

Antworten