# Zahlen im Array überprüfen



## clarkgabel (30. Januar 2017)

Hey Mitglieder,
wie kann ich überprüfen, wenn ich ein Array mit Zufallszahlen habe, ob die Zahl schon mal vorhanden war (z.B. mit einer if Bedingung) und diese dann anschließend um eine zu erhöhen.
Ich habe bereits einen Quellcode, aber habe das Gefühl, dass meine if Bedingung nicht ganz richtig ist.
Könntet ihr mir da weiterhelfen?
Hier der Quellcode:

```
#include<stdio.h>

#include<stdlib.h>

int main(void)
{

    int zahl[5],i,anz=5,n,temp,j=anz;

    for(i=0;i<anz;i++)

    {

        n=rand()%49;

        zahl=n;

        if(zahl==n)

        {
            zahl=n+1;
        }
        printf("%d\n", zahl);
    }
while(j--)
  {
      for(i=0;i<j;i++)
      {
          if(zahl[i-1]>zahl)
          {
              temp=zahl;

              zahl=zahl[i-1];

              zahl[i-1]=temp;
  }
      }
printf("%d\n", zahl);

  }}
```


----------



## vfl_freak (30. Januar 2017)

Moin,
nutze bitte die Code-Tags!! So bekommt man ja Augenkrebs!! 
Tipp: im Editor gibt es das Icon "Einfügen ..." :-]

Habe jetzt den Code nicht im Detail nachvollzogen (auch weil mir nicht wirklich klar, was Du womit versuchst ...), aber was mir spontan auffiel:
was soll diese Schleife Deiner Meinung nach tun (oder besser: wann soll sie terminieren?) : *while( j-- )* ??? 

Gruß Klaus


----------



## clarkgabel (30. Januar 2017)

Was sind Code-Tags?
das while(j--) gehört zum Bubblesort meine Frage war eher auf die if Bedingung weiter oben bezogen... Wie kann ich überprüfen, ob die Zahl schon mal vorkam?


----------



## vfl_freak (30. Januar 2017)

Moin,

Code-Tags formatieren deinen Code zu einer lesbaren Form: [code=Java]...myMagnificentCode...[/code]



clarkgabel hat gesagt.:


> while(j--) gehört zum Bubblesort


Das wäre mir neu !! :-]
Und so wir Du es hast, ist es eine 1a-Endlosschleife, so es denn überhaupt funktioniert !

Zudem hast zwei if-Bedingungen drin!
Welche meinst Du ??
Dies hier

```
zahl[I]=n;
if(zahl[I]==n)
```
macht jedesfall keinen Sinn!!
Du weist 'zahl' den Wert von 'n' zu und schaust dann, ob beide Werte gleich sind ?? 
Und nebenbei: Schreibe den Index 'I' besser klein, also 'i' !!

Gruß Klaus


----------



## Technipion (30. Januar 2017)

Hallo clarkgabel,
ohje, ich weiß gar nicht genau wo ich anfangen soll. Also zuerst mal, da du ja neu bist, wir umschließen geposteten Code hier mit Code-Tags. Für deinen C-Code würdest du anstatt
#CODE
zu posten stattdessen
[ code=c]#CODE[ /code]
schreiben (ohne Leerzeichen). Dadurch wird alles viel lesbarer und man erkennt direkt was Sache ist.
Ich habe versucht deinen Code mit GCC 5.4 zu compilieren, allerdings hat er mir eine ganze Reihe Errors zurückgegeben. Ich habe jetzt deinen ursprünglichen Code so modifiziert, dass er sich compilieren ließ. Allerdings musste ich raten, welche Indizes du an welcher Stelle gemeint hast. Das hier kam dabei heraus:


Spoiler





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


int main(int argc, char* argv[])
{
   
    int zahl[5], i, anz = 5, n, temp, j = anz;
   
    for (i = 0; i < anz; i++) {
       
        n = rand() % 49;
       
        //zahl = n; // erzeugt ERROR
        zahl[i] = n;
       
        /*if (zahl == n) { // erzeugt ERROR
           
            // wozu diese Schleife?
            zahl = n+1;
        }*/
       
        //printf("%d\n", zahl); // gibt die Adresse des Arrays aus
        printf("%d\n", zahl[i]);
    }
   
    while (j--) {
       
        for (i = 0; i < j; i++) {
           
            //if (zahl[i-1] > zahl) { // erzeugt ERROR
            if (zahl[i-1] > zahl[i]) {
               
                //temp = zahl; // erzeugt ERROR
                temp = zahl[i];
               
                //zahl = zahl[i-1]; // erzeugt ERROR
                zahl[i] = zahl[i-1];
               
                zahl[i-1] = temp;
            }
        }
       
        //printf("%d\n", zahl); // gibt die Adresse des Arrays aus
        printf("%d\n", zahl[i]);
       
    }
   
    return 0;
}
```



Ich habe das Programm dann compiliert und laufen lassen, er hat mir das hier ausgegeben:

```
15
39
37
5
29
29
39
37
15
5
```
Übrigens: Da der Zufallsgenerator nicht initialisiert wurde, gibt er bei jedem Aufruf genau die gleiche Zahlenfolge aus.
Ich bin mir relativ sicher, dass du nicht so etwas wolltest. Die 49 schaut für mich danach aus, als würdest du Lottozahlen simulieren wollen. Dein aktueller Code ist leider so undurchsichtig für mich, dass ich keine Ahnung habe was du dir dabei gedacht hast . @vfl_freak Die _while_ terminiert wenn j = 5 nach ein paar Durchläufen 0 erreicht hat. Ist aber natürlich kein sauberer Stil .

Ich habe selbst schnell ein Programm geschrieben, dass die 5 Zufallszahlen berechnet. Hier ist der Code:


Spoiler





```
#include <stdio.h>      // for printf, NULL
#include <stdlib.h>     // for srand, rand
#include <time.h>       // for time


#define ANZAHL      5
#define RAND_LIMIT  49


int main(int argc, char* argv[])
{
   
    int zahl[ANZAHL];
    // Hier müsste das Array eigentlich initialisiert werden,
    // das ist hier aber nicht notwendig, da wir das on-the-fly machen.
   
    // Initialisiere den Zufallsgenerator
    srand(time(NULL));
   
    // Fülle die erste Zahl
    zahl[0] = rand() % RAND_LIMIT;
   
    for (int i = 1; i < ANZAHL; i++) {
       
        // Setze die i-te Zahl ein. Sie wird dadurch auch initialisiert.
        zahl[i] = rand() % RAND_LIMIT;
       
        int zahlKommtSchonVor = 0; // 0 = false, 1 = true
       
        // Teste jetzt, ob die Zahl schon irgendwo vorkommt
        for (int j = i-1; j >= 0; j--) {
           
            if (zahl[j] == zahl[i]) {
                // Treffer
               
                zahlKommtSchonVor = 1;
                break;
            }
        }
       
        if (zahlKommtSchonVor == 1) {
           
            // Verringere i um 1, damit die aktuelle Zahl
            // neu berechnet wird
            i--;
        }
    }
   
    // Alle Zahlen sind jetzt bestimmt
    // Also gib sie aus
   
    for (int i = 0; i < ANZAHL; i++) {
       
        printf("%d\n", zahl[i]);
    }
   
    // Fertig, alles lief gut.
    return 0;
}
```




@clarkgabel Bitte lies dir beide Codeschnipsel gut durch und überlege dir was die Kommentare bedeuten. Falls du noch Fragen hast, antworte ich gerne . Es ist aber wichtig, dass du verstehst warum

```
int zahl[5];
.
.
.
if (zahl == 3) {
...
```
nicht geht. Generell gilt: Nicht so viel rumtricksen (wie mit der _while_), sondern lieber soliden und verständlichen Code schreiben!

Gruß Technipion


----------



## clarkgabel (30. Januar 2017)

Alles klar ich danke dir und wie mache ich am besten den Bubblesort?


----------



## Technipion (30. Januar 2017)

Hallo clarkgabel,
bitte nimm dir das was ich oben geschrieben habe zu Herzen. Ich habe den Eindruck, dass du die Lösungen des Forums für Übungsaufgaben benutzt und es dir gar nicht genau anschaust. Du musst mir Recht geben: Zumindest erweckt der Fibonacci-Post zusammen mit diesem jetzt den Eindruck. Also bitte: Schau dir den Code an und frage nach wenn etwas unklar ist .
Was den Bubblesort angeht, lass' ihn uns doch schnell designen. 

Also wir wollen alle Zahlen im Array der Größe nach sortieren. Da so ein Array verdammt groß sein kann, sind wir durch die vielen Einträge überfordert. Was wir aber sogar im Schlaf tun können, ist zwei Zahlen ihrer Größe nach zu ordnen. Das ist ziemlich einfach, die kleinere Zahl schreiben wir links hin und die größere rechts.
Der Bubblesort-Algorithmus geht jetzt so: Wir fangen mit dem rechtesten Zahlenpaar im Array an. Diese beiden Zahlen "ordnen" wir ihrer Größe nach, d.h. wir schreiben die kleinere Zahl links hin und die größere rechts. Dann wandern wir eine Stelle nach links, d.h. wir schauen uns jetzt das vorletzte Zahlenpaar an (also die vorvorletzte und die vorletzte Zahl). Die ordnen wir auch wieder wie gehabt. Dann wandern wir wieder eine Stelle nach links, usw.
Wenn wir bei dem vordersten Zahlenpaar angekommen sind, ordnen wir auch das. Jetzt steht die kleinste Zahl im Array definitiv ganz vorne, denn wir haben sie garantiert irgendwo beim Durchlaufen aufgeschnappt und dann immer wieder nach links getauscht. Also: Die kleinste Zahl steht ganz vorne, d.h. wir können so tun als gäbe es sie gar nicht mehr. Wir tun also im nächsten Durchlauf genau das gleiche, aber laufen nicht bis ganz vorne, sondern ignorieren die erste Zahl.
Nach dem zweiten Durchlauf steht dann ganz vorne die kleinste Zahl, und an zweiter Stelle steht die zweitkleinste Zahl. Wir wiederholen das alles so lange, bis an der vorletzten Stelle die zweitgrößte Zahl steht (und an der letzten dann logischerweise die größte). Das ist Bubblesort.

Hier ist der Pseudocode dafür, bitte versuche mal ihn in C zu implementieren. Falls du nicht weiterkommst, frag einfach nach .

```
BUBBLESORT(A)
  for i = 1 to A.länge - 1
      for j = A.länge downto i + 1
          if A[j] < A[j - 1]
              vertausche A[j] mit A[j - 1]
```
Code entnommen aus _Algorithmen - Eine Einführung_, Cormen T. et al, Oldenbourg Wissenschaftsverlag GmbH

Ich bin zuversichtlich, dass du das hinkriegst .

Gruß Technipion


----------



## cwriter (30. Januar 2017)

Kurz OT:

```
while(j--)
//ist
repeat:
if(j != 0) {
j=j-1;
goto repeat;
}
j=j-1;
```
Und terminiert dadurch sehr wohl - ob es guter Stil ist, darüber lässt sich streiten.



clarkgabel hat gesagt.:


> Alles klar ich danke dir und wie mache ich am besten den Bubblesort?




```
for(size_t i = n; i > 0; i--)
for(size_t j = 0; j < i; j++)
if(a[j] > a[j+1])
swap(a[j], a[j+1]);
```
Damit's nicht ganz so langweilig ist, darfst du swap() selbst bauen.
Allerdings ist BubbleSort miserabel - zumindest im Sequentiellen Umfeld (Parallel ist es wiederum so ziemlich _die_ beste Methode). Daher würde ich auf Quicksort umsteigen, wenn dein Array grösser wird (O(n^2) vs O(nlog) für's Sortieren.



Technipion hat gesagt.:


> Nicht so viel rumtricksen (wie mit der _while_), sondern lieber soliden und verständlichen Code schreiben!


In der Kürze liegt die Würze 
Aber leider ist es manchmal zu kurz und daher versalzen, wenn man nicht aufpasst.
Und in diesem Fall: Wenn man die Compilerwarnungen ignoriert. Daher: Fancy C ist wunderschön, und es kann guter Stil sein, Dinge in Kurznotation auszudrücken. Aber man sollte die Langform verstanden haben.

Gruss
cwriter


----------



## clarkgabel (30. Januar 2017)

Nein nein Technipion, ich habe alles verstanden, da du ja zu jedem Schritt eine logische Erklärung beigefügt hast, danke vielmals dafür.


----------



## clarkgabel (30. Januar 2017)

über eine Sache stolpere ich jedoch, warum hast du in die erste if Bedingung bei den Zufallszahlen j=i-1 stehen?


----------



## Technipion (31. Januar 2017)

Hallo clarkgabel,
meinst du in der inneren for-Schleife? Da wir in der äußeren for-Schleife die Zahl mit dem Index i bestimmen, laufen wir zur Überprüfung alle Zahlen vom Index 0 bis zum Index (i-1) ab (bzw. umgekehrt). Die innere for-Schleife beginnt also bei j=i-1 und endet bei j=0.

Übrigens: Wenn dir nachdem du etwas gepostet hast noch etwas einfällt, das du gerne in den Post aufnehmen möchtest, dann musst du nicht doppelposten. Du kannst unter deinem alten Beitrag auf "Bearbeiten" drücken, dann kannst du Dinge ergänzen.

Gruß Technipion


----------

