Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Problem mit simplem C-Quellcode (https://www.delphipraxis.net/40961-problem-mit-simplem-c-quellcode.html)

Dust Signs 23. Feb 2005 20:01


Problem mit simplem C-Quellcode
 
Hi :)!

Da wir in Informatik grad den Stoff vom ersten Semester etwas wiederholen (gab eine ganze Menge "Nicht genügend" bei der Vorlesungsklausur ;)) sollten wir ein Programm schreiben, das folgendes macht:

Zitat:

Zitat von Angabe
30 Matrosen sind im Kreis aufgestellt und müssen zu 7 auszählen. Wer eine 7 hat, geht über Bord. Wer mit dem Abzählen beginnt wird vom Kapitän bestimmt. Die Reihenfolge der über Bord gegangenen Matrosen soll ausgegeben werden und der übriggebliebene Matrose.

Das Deutsch meines Profs ist naja.... sagen wir mal etwas dürftig, daher hier nochmal in Kurzform: 30 Matrosen zählen von 1-7, wer die sieben hat, fliegt, dann wird wieder bei eins zu zählen begonnen. Welcher Matrose bleibt übrig?

Ich komme einfach weiter (wer zum Abzählen anfängt bau ich ein, wenn das Prog. funktioniert ^^): laut Prof. ist die Lösung des Beispiels (sofern der erste Matrose zu zählen beginnt) Matrose Nr. 23 - der sollte übrigbleiben. Bei mir bleibt Matrose Nr. 20 über - da stimmt also was nicht. Wer findet den Fehler?

Code:
#include <stdio.h>

int matrosen[30];

int zaehler = 0; //Wenn eine Runde fertig: bei welchem Wert wurde aufgehört zu zählen

int anzahl_matrosen_uebrig = 30;

int MatrosenFuellen() {

  int i; //Schleifendummy

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

    matrosen[i] = i + 1;

    }

  }

int JederSiebteRaus() {

  int i; //Schleifendummy

  printf("Neue Runde...\n");

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

    zaehler++;

    if (zaehler == 7) {

      zaehler = 0;

      printf("Matrose #%d (Array-Index %d) fliegt...\n", matrosen[i], i);

      matrosen[i] = 0; //Matrose "löschen"

      }

    }

  printf("Wir haben bei %d aufgehört zu zählen.\n", zaehler);

  }


int Nullfelderloeschen() {

  int i, j, k; //Schleifendummies

  int anzahl; //Anzahl speichern!!! Sonst Bug, weil anzahl_matrosen_uebrig in der Schleife hinuntergezählt wird *argx*

  anzahl = anzahl_matrosen_uebrig;

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

    if (matrosen[i] == 0) { //Wenn Matrose Wert null hat, "löschen" (Matrosen nach vor "schieben")

      printf("Matrose ging über Bord... (Array-Index %d)\n", i);

      for (j = i + 1; j < anzahl/*_matrosen_uebrig*/; j++) {

        matrosen[j - 1] = matrosen[j]; //Nach oben "schieben"

        }

      anzahl_matrosen_uebrig--;

      }

    }

  }

int main() {

  MatrosenFuellen(); //Initialisieren

  printf("Lustiges Matrosenfliegen\n");
  printf("========================\n\n");

  while (anzahl_matrosen_uebrig > 1) {

    JederSiebteRaus();
    Nullfelderloeschen();

    printf("Noch %d Matrosen übrig\n", anzahl_matrosen_uebrig);

  }

  printf("Übrig ist Matrose #%d\n", matrosen[0]);

  return 0;

  }
Sorry für die hässliche Formatierung und die wenigen Kommentare - wir hatten grade mal eine halbe Stunde dafür Zeit.

Dust Signs

PS. Crossposting DF

Binärbaum 23. Feb 2005 20:13

Re: Problem mit simplem C-Quellcode
 
Ich würde das nicht mit einem Array machen, sondern mit einer ringförmig verketteten Liste. Dabei hat jedes Listenelement einen Zeiger auf seinen Nachfolger und das letzte Element zeigt wieder aufs erste. Dann läuft man einfach die Liste durch und löscht aller sieben Elemente eins raus. Das Element, welches am Ende übrig bleibt, repräsentiert den letzten Matrosen. Ist IMHO besser geeignet als ein Array.

MfG
Binärbaum

Dust Signs 23. Feb 2005 20:23

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Binärbaum
Ich würde das nicht mit einem Array machen, sondern mit einer ringförmig verketteten Liste. Dabei hat jedes Listenelement einen Zeiger auf seinen Nachfolger und das letzte Element zeigt wieder aufs erste. Dann läuft man einfach die Liste durch und löscht aller sieben Elemente eins raus. Das Element, welches am Ende übrig bleibt, repräsentiert den letzten Matrosen. Ist IMHO besser geeignet als ein Array.

MfG
Binärbaum

Im ersten Semester ham in C nichts außer Schleifen und Arrays gemacht, Pointer nichtmal angefangen ;) ergo auch keine verketteten Listen ;)

Dust Signs

freak4fun 23. Feb 2005 20:27

Re: Problem mit simplem C-Quellcode
 
Edit: Totaler Unsinn. Sry.

MfG
freak

Binärbaum 23. Feb 2005 20:37

Re: Problem mit simplem C-Quellcode
 
Wenn ich mich recht erinnere, war die Deklaration für eine Liste etwa folgende:
Code:
typedef struct liste *PtrListe;
typedef struct liste {int nummer; //Nummer des Matrosen
                      PtrListe next;//Zeiger auf nächsten "Matrosen"
                     };
Beim Erzeugen der Listenelemente muss man den Speicher dafür mit malloc bereitstellen und beim Löschen wieder mit free freigeben. Um die Pointer muss man sich natürlich auch kümmern.

[Edit]
Ich hoffe doch, dass ihr inzwischen Zeiger kennengelernt habt, die werden in C nämlich ziemlich oft verwendet. Falls nicht, dann würde ich mich beim Prof beschweren :mrgreen: und erstmal mit Arrays weiterarbeiten.
[/Edit]

MfG
Binärbaum

Dust Signs 23. Feb 2005 20:39

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Binärbaum
Wenn ich mich recht erinnere, war die Deklaration für eine Liste etwa folgende:
Code:
typedef struct liste *PtrListe;
typedef struct liste {int nummer; //Nummer des Matrosen
                      PtrListe next;
                     };
Beim Erzeugen der Listenelemente muss man den Speicher dafür mit malloc bereitstellen und beim Löschen wieder mit free freigeben. Um die Pointer muss man sich natürlich auch kümmern.

MfG
Binärbaum

Unser Prof wills aber mit den reinen Erstsemesterkenntnissen... und da sind eben keine Zeiger dabei ;)

Dust Signs

Binärbaum 23. Feb 2005 20:42

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Dust Signs
Unser Prof wills aber mit den reinen Erstsemesterkenntnissen... und da sind eben keine Zeiger dabei ;)

Dust Signs

:shock: Dann musst du es halt über Arrays realisieren.

Robert Marquardt 23. Feb 2005 20:55

Re: Problem mit simplem C-Quellcode
 
Die einfachste Loesung ist natuerlich eine TStringList (am besten eine TListBox).
Sie wird mit 30 Strings "Matrose 1" bis "Matrose 30" gefuellt und dann machen wir uns ans zaehlen.
Delphi-Quellcode:
  // Los gehts bei Matrose 1 = Index 0
  I := 0;
  // der Zaehler bis 7
  N := 0;
  // bis nur noch ein Matrose uebrig ist
  while ListBox1.Count > 1 do
  begin
    // erst N inkrementieren, daher Initialisierung auf 0
    Inc(N);
    if N = 7 then
    begin
      // den Matrosen killen
      ListBox1.Delete(I);
      // damit die Listbox auch den Fortgang anzeigt
      ListBox1.Update;
      // Zaehler zuruecksetzen
      N := 0;
    end
    else
      // Naechster Matrose. Wurde einer gekillt, dann sind die Nachfolger aufgerueckt.
      Inc(I);
    // Ende der Liste
    if I >= ListBox1.Count then
      // zurueck zum Anfang
      I := 0;
  end;

Binärbaum 23. Feb 2005 21:01

Re: Problem mit simplem C-Quellcode
 
Soweit ich das verstanden habe, war die Aufgabe mit C zu lösen, nicht mit Delphi.

Dust Signs 23. Feb 2005 21:10

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Binärbaum
Soweit ich das verstanden habe, war die Aufgabe mit C zu lösen, nicht mit Delphi.

Eigntlich schon :gruebel:

Dust Signs

Binärbaum 23. Feb 2005 21:18

Re: Problem mit simplem C-Quellcode
 
Naja, wir sind hier aber auch in einem Forum, das sich auf Delphi spezialisiert hat, und da ist sowas ja in Ordnung. Allerdings gehört es nicht zur Lösung des Problems :warn:
@Robert Marquardt:
Nimms mir bitte nicht übel, ich würde es auch lieber in Delphi machen, aber scheinbar haben die in der Uni von Dust Signs kein Delphi.

MfG
Binärbaum

Dust Signs 23. Feb 2005 21:24

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Binärbaum
@Robert Marquardt:
Nimms mir bitte nicht übel, ich würde es auch lieber in Delphi machen, aber scheinbar haben die in der Uni von Dust Signs kein Delphi

Delphi lernen wir an unserer FH nicht, nur C, C++, Java etc. Alles, nur kein Delphi :(. Da wir uns im ersten und zweiten Semester ausschließlich mit C befassen wird eine Delphilösung wohl kaum genügen ;) (wär mir persönlich auch lieber).

Habs jetzt anders lösen können:

Code:
#include <stdio.h>

int matrosen[30];

int zaehler = 0; //Wenn eine Runde fertig: bei welchem Wert wurde aufgehört zu zählen

int anzahl_matrosen_uebrig = 30;

int MatrosenFuellen() {

  int i; //Schleifendummy

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

    matrosen[i] = i + 1;

    }

  }

int JederSiebteRaus() {

  int i; //Schleifendummy

  printf("Neue Runde...\n");

  for (i = 0; i < 30; i++) {
 
    if (matrosen[i] != 0) { //Matrose noch da

      zaehler++;

      if (zaehler == 7) {

        zaehler = 0;

        printf("Matrose #%d fliegt...\n", matrosen[i]);

        matrosen[i] = 0; //Matrose "löschen"
      
      anzahl_matrosen_uebrig--; //Ein Matrose weniger

        }
      
   }

    }

  printf("Wir haben bei %d aufgehört zu zählen.\n", zaehler);

  }
 
int LetzterMatrose() {

  int i; //Schleifendummy
 
  for (i = 0; i < 30; i++) {
 
    if (matrosen[i] != 0) {
   
     return matrosen[i];
    
     }
 
    }

  }

int main() {

  MatrosenFuellen(); //Initialisieren

  printf("Lustiges Matrosenfliegen\n");
  printf("========================\n\n");

  while (anzahl_matrosen_uebrig > 1) {

    JederSiebteRaus();

    printf("Noch %d Matrosen übrig\n", anzahl_matrosen_uebrig);

  }

  printf("Übrig ist Matrose #%d\n", LetzterMatrose());

  return 0;

  }
Danke trotzdem für eure Hilfe :)
Dust Signs

Robert Marquardt 24. Feb 2005 05:58

Re: Problem mit simplem C-Quellcode
 
Das mit dem C hab ich irgendwie verpasst.
Da muss man aber nur ein Array statt der TStringList deklarieren und das Delete mit memmove implementieren.
Der Rest des Algorithmus bleibt bestehen.

Chewie 24. Feb 2005 13:26

Re: Problem mit simplem C-Quellcode
 
Inkrementier deinen Zähler doch einfach jedesmal und fürh eine Modulo-<Größe des Arrays>-Operation durch. Dann kriegst du automatisch dein Umklappen hin.
Ein Ringpuffer ist IMHO genauso leicht mit ARrays zu realisieren wie mit verk. Listen.

Luckie 24. Feb 2005 13:47

Re: Problem mit simplem C-Quellcode
 
Für den Algorithmus ist die Sprache doch vollkommen unerheblich. Und wenn man in einem Delphi-Forum fragt, dann sollte man auch damit rechnen, das ganze in Delphi präsentiert zu bekommen. ;)

Dust Signs 24. Feb 2005 13:48

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Luckie
Für den Algorithmus ist die Sprache doch vollkommen unerheblich. Und wenn man in einem Delphi-Forum fragt, dann sollte man auch damit rechnen, das ganze in Delphi präsentiert zu bekommen. ;)

Was meinst du warum ich in dieser Sparte gepostet hab ;)

Dust Signs

Binärbaum 24. Feb 2005 15:20

Re: Problem mit simplem C-Quellcode
 
Zitat:

Zitat von Luckie
Für den Algorithmus ist die Sprache doch vollkommen unerheblich. Und wenn man in einem Delphi-Forum fragt, dann sollte man auch damit rechnen, das ganze in Delphi präsentiert zu bekommen. ;)

Das mag schon sein und ist ja auch nichts schlechtes. Allerdings gibt es in C keine Komponente TStringList mit den dazugehörigen Methoden/ Prozeduren wie in Delphi. Deshalb war der Code in dem Moment wenig hilfreich.

MfG
Binärbaum

Luckie 24. Feb 2005 15:27

Re: Problem mit simplem C-Quellcode
 
wie schon gesagt, für den reinen Algorithmus sind Sprache und verwendete Komponente vollkommen unerheblich.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:56 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz