Gedanken Hänger in drei C# Aufgaben

theqwe

Aktives Mitglied
Hallo Zusammen,

ich bin zurzeit in einer Umschulung und muss mich von Java auf C# umorientieren. Ansich ist es überhaupt nicht schwierig, nur irgendwie verhält es sich für mich anders, als damals mit Java. Ich hänge bei genau drei Aufgaben bei der Umsetzung:

Ich komme hier nicht weiter, wie ich die zufällige Lottozahl neu generiere, wenn sie im Array schon vorhanden ist. Am besten keine vorgefertigten Methoden nutzen.
[CODE lang="csharp" title="Aufgabe 1"]/*Speichern Sie mit Hilfe des Zufallszahlengenerators die Lottozahlen vom nächsten Samstag in einem eindimensionalen Array.
Achtung: Keine Lottozahl darf doppelt vorkommen.*/

private static void Lottozahlen()
{
Random zufall = new Random();
int[] zahlen = new int[6];
int lottozahl;

for (int i = 0; i < zahlen.Length - 1; i++) //6 Durchläufe für 6 Zahlen
{
lottozahl = zufall.Next(1,50);

for(int j = 0; j < zahlen.Length; j++) //Im Array prüfen
{
if(zahlen[j] != 0)
if(zahlen[j] == lottozahl)
break;
}
}
}[/CODE]

Hier ist das Problem, dass ich die Abfragen nicht hinbekomme. Es wird nie eine Ausgabe stattfinden. Für eine bessere Übersicht habe ich den Zähler nur bis 100 laufen lassen und noch kein Array erzeugen lassen.
[CODE lang="csharp" title="Aufgabe 2"]/*Entwickeln Sie ein Programm für eine statistische Erhebung. Die Personalnummern sind 5-stellig von 00001 bis 17689.
Es soll nur ein Teil der Mitarbeiter befragt werden. Ihr Programm soll jeden 6. Mitarbeiter, aber nicht jeden 8. Mitarbeiter,
dafür aber jeden 48. Mitarbeiter auswählen und in einem eindimensionalen Array ablegen. Zeigen Sie die ausgewählten Mitarbeiter an.*/

private static void Personalnummer()
{
for(int i = 0; i < 100; i++)
{
if ((i % 6) == 0)
if ((i % 8 == 0))
return;
else if((i % 48) == 0)
Console.WriteLine(i + "\n-----------");
}
}[/CODE]

Hier ist die foreach Schleife das Problem. Sie gibt mir mehr char's aus, als ich eingespeichert habe. Es sollten nur 7x '_' ausgegeben werden. Natürlich ist es noch nicht fertig, aber der Anfang sollte ja erstmal funktionieren, dass ich die Anzahl der zu suchenden Buchstaben als Unterstriche ausgegeben bekomme.
[CODE lang="csharp" title="Aufgabe 3"]private static void Hangman()
{
string wort = "hangman";
char[] wortArray = new char[wort.Length];
char[] tempArray = new char[wort.Length];
wortArray = wort.ToCharArray();
int versuche = 10;
int zaehler = 0;
Boolean gewonnen = false;

for(int i = 0; i < tempArray.Length; i++)
{
tempArray = '_';
}

while(versuche >= zaehler && gewonnen == false)
{
Console.Clear();
char eingabe;

foreach (char c in tempArray) // wird nicht benötigt
{
Console.Write(tempArray);
}

Console.Write("Welchen Buchstabe wählst Du?: ");
eingabe = Convert.ToChar(Console.ReadLine());

for (int i = 0; i < wortArray.Length; i++)
{
if (wortArray == eingabe)
tempArray = eingabe;
}
}
}[/CODE]
//EDIT: Okay, ich habe herausgefunden, dass die foreach Schleife gar nicht gebracht wird, sondern die Ausgabe von tempArray allein reicht.

Ich habe bestimmt große Denkfehler in meinem Code und die Wärme macht es gerade nicht einfach. Ich möchte aber gerne den Code bis morgen geschafft habe.

Deshalb freue ich mich auf eure Hilfe und bedanke mich im Voraus. 😉
 
Zuletzt bearbeitet:
K

kneitzel

Gast
Also generell wären hier meine Tipps (Unabhängig von der Sprache!):
a) Unterteile in Methoden! Du hast Probleme, die Komplexität zu beherrschen? Dann ist die Komplexität zu hoch! Also musst Du diese verkleinern, in dem Du eine Problematik unterteilst!
b) Formuliere immer erst genau, was Du machen willst. Das ist auch das a und o - denn wenn Du Dir nicht im klaren bist, was da gemacht werden soll, dann wäre es schlicht Zufall, wenn der Code das macht, was er soll.

a und b kann man auch zusammen fassen.

Was ist denn die erste Aufgabe?
So lange noch nicht alle Lottozahlen gezogen wurden: Ziehe eine Lottozahl. Ist diese noch nicht enthalten, dann füge diese hinzu.
Kannst Du in Code schreiben:
C#:
// So lange noch nicht alle Lottozahlen gezogen wurden
while (!WurdenAlleLottozahlenGezogen())
{
    //Ziehe eine Lottozahl.
    int lottozahl = ZieheLottozahl();
    // Ist diese noch nicht enthalten, dann füge diese hinzu.
    if (!IstZahlInLottozahlenEnthalten(lottozahl))
    {
        FuegeLottozahlHinzu(lottozahl);
    }
}

Ok, Lottozahlen muss man irgendwie speichern und dann brauchen die Methoden diese auch, also kommt das Array noch dazu und die lottozahlen werden überall als Argument mit übergeben.

Und dann kommen die fehlenden Methoden. WurdenAlleLottozahlenGezogen kann prüfen, ob die letzte Zahl eine 0 ist. Oder vorsichtshalber, ob eine Zahl außerhalb des Wertebereichs ist (<1 oder >49).

Mit so einem Ansatz hast Du kleine Methoden, die alle eine geringe Komplexität haben und bei jeder ist klar, was die Methode macht. Und die Korrektheit ist relativ einfach zu sehen.

Ansonsten Fehler:
Bei Aufgabe 1 sehe ich keine Prüfung, ob eine Zahl bereits gezogen wurde ...
Bei Aufgabe 2 ist das return Unsinn. Da soll evtl. ein continue hin? Aber ist egal -> a und b beherzigen. Der Code ist offensichtlich zu komplex, so dass Du diesen nicht überblicken kannst!
Bei Aufgabe 3 ist das Problem wohl eher, dass Du schlechte Bezeichner hast. Was willst Du machen? Für jedes Element aus dem temporären Array (Nenne es vernünftig. Dafür musst Du einen vernünftigen Begriff finden! temporär ist es, da es eine lokale Variable ist ... und ja, der Typ ist ein Array. Und Deinen Papa nennst Du immer nur männlicher Mensch?) willst Du das temporäre Array ausgeben?
Du willst für jedes Element aus dem Array das Element ausgeben.
 

theqwe

Aktives Mitglied
Hallo und vielen Dank für deine Hilfe.

Die Ansätze nehme ich gerne war und werde diese definitiv umsetzen. Das Einzige, was mich bis jetzt davon abgehalten hat, ist dass ich in einer Gruppe programmiere, die davon noch nicht so viel Ahnung haben und gerne alles "in einem Block" haben. Sie kennen sich mit Methoden, Parameter und Rückgabewerten noch nicht so gut aus.

1. if(zahlen[j] == lottozahl) prüft doch, ob die gezogene lottozahl in dem zahlen-Array an Stelle j liegt oder nicht?

2. Da stört mich besonders, dass das so verzweigt ist. Sind die Bedingungen denn überhaupt richtig? Also ein gemeinsamer Nenner von 6 und 8 wäre ja 24. 24 wäre wieder ein 6ter Teilnehmer, gleichzeitig aber auch ein 8ter und darf somit nicht teilnehmen.

3. Ja stimmt. Die Benennung ist manchmal chaotisch. Da muss ich defintiv dran arbeiten. Das gesuchte Wort soll später in dem "tempArray" nach erraten eines Buchstabens die Unterstrichen ersetzen. Sozusagen zeigt das "tempArray", die Anzahl der Buchstaben in verschlüsselter Form. Ein Unterstrich soll dann durch den gefunden Buchstaben ersetzt werden.
 
K

kneitzel

Gast
Ja, aber danach kommt nur ein Break. Und das spielt keine Rolle, denn n der Schleife wird eh nicht geprüft.

Prinzipiell sieht es gut aus. Aber das liesse sich auch vereinfachen zu einem logischen Ausdruck.

Dieses vorgeschlagene Vorgehen solltest du in der Gruppe einmal vorschlagen und durchgehen. Der Umgang mit Methoden ist eine wichtige Grundlage und wenn das noch nicht sitzt, dann sollte man es dringend üben.

Gerade am Anfang vereinfacht es einiges, wenn man lesbaren Code hat ...
 

theqwe

Aktives Mitglied
So,
wenn ich die Überprüfung der gezogenen Lottozahl in eine Methode schreibe, die einen boolean zurückgibt, könnte ich das ganze in einer do-while Schleife verankern. Also generiere solange eine Zahl bis diese nicht mehr doppelt vorkommt. Das funktioniert dann. Trotzdem hätte ich es gerne mal so in einer Methode verzweigt :D

Aufgabe 2 funktioniert jetzt auch, indem ich den XOR Operator verwende:
C#:
private static void Personalnummer()
{
   for(int i = 1; i < 100; i++)
   {
      if ((i % 6) == 0)
          if ((i % 8 != 0) ^ (i % 48 == 0))
              Console.WriteLine($"Teilnehmer {i}");
              Console.WriteLine("-------------------");
   }
}
Die zweite if-Anweisung kann ich nicht in die erste kriegen oder? Zumindest kriege ich es nicht mehr kompakter. Alle Bedingungen sind gegeben.
 
K

kneitzel

Gast
Interessant, auf was für Lösungen du so kommst .... Das Problem war doch nur, dass etwas, das durch 48 teilbar ist, auch durch 8 Teilbar ist.

Daher hättest du bei einzelnen Prüfungen erst die 48 prüfen müssen.

Ansonsten ist die Bedingung doch: durch 6 teilbar und ( nicht durch 8 teilbar oder durch 48 teilbar)
Das kann man dann jetzt in Programmcode überführen.
 

theqwe

Aktives Mitglied
Sorry, da muss ich nochmal nachfragen. Wir sollen ja jeden 48ten Teilnehmer befragen, auch wenn er durch 8 teilbar ist "...aber nicht jeden 8. Mitarbeiter, dafür aber jeden 48. Mitarbeiter...". Wenn ich die if-Anweisung so umsetze, wie vorgeschlagen, dann bleibt die 48 aber aus.
 
K

kneitzel

Gast
Also der Text ist ja
Ihr Programm soll jeden 6. Mitarbeiter, aber nicht jeden 8. Mitarbeiter,
dafür aber jeden 48. Mitarbeiter auswählen
Das habe ich nur etwas verkürzt und in die Sprache umgesetzt die näher ist an der Programmiersprache.

Wenn wir das mit 48 weg lassen, dann haben wir ja erst einmal

jeder 6te und nicht jeder 8te.
Wenn die 48 jetzt dazu genommen wird, dann bedeutet es, dass der Teil wahr ist, wenn nicht der 8te oder der 48te wäre.
Das nicht bezieht sich dabei natürlich nur auf den 8ten ...

Also verkürzt dargestellt mit den Symbolen der Programmiersprache:
6te && (!8te || 48te)
Wenn ich die if-Anweisung so umsetze, wie vorgeschlagen, dann bleibt die 48 aber aus.

Dann musst Du mir einmal zeigen, wie Du es umgesetzt hast. Denn wenn ich jetzt nicht gerade Tomaten auf den Augen habe, dann müsste das genau so funktionieren.
 

theqwe

Aktives Mitglied
Hmm jetzt bin ich ziemlich verwirrt. Ich habe es noch einmal ausgeführt. Jetzt wird zwar die 48 angezeigt, nur z.B. keine 6, dafür aber die 24, die ja durch 8 teilbar ist 🤨

C#:
if (i % 6 == 0 && ((i & 8) != 0 || (i % 48) == 0))
    Console.WriteLine(i.ToString("D5") + "\n-----------");

Wo mache ich denn den Fehler?
 

M.L.

Top Contributor
Weiterhin könnte man sich längerfristig an ein auf C# spezialisiertes Forum wenden: (z.B.) www.mycsharp.de (im Vorab: unreflektierte x-Postings oder Verändern von Ursprungscodes bitte unterlassen). Und mit der neusten C#-Version kann man "ältere"Codeartefakte unterlassen und deren Hinzufügen dem Compiler überlassen.
 

theqwe

Aktives Mitglied
Du prüfst da i & 8 aber das sollte wohl % 8 heißen. Evtl. ist das aktuell der Fehler.
Entschuldige die verspätete Antwort. Das war das Problem. Zu schnell getippt oder die Wärme... hauptsache es läuft. Vielen Dank dafür. Alle Aufgaben laufen jetzt perfekt. Deinen Rat habe ich auch angenommen und in der Gruppe die Vorteile und auch Notwendigkeit von Methoden besprochen. Somit lassen sich die Aufgaben auch leichter realisieren.

Weiterhin könnte man sich längerfristig an ein auf C# spezialisiertes Forum wenden: (z.B.) www.mycsharp.de (im Vorab: unreflektierte x-Postings oder Verändern von Ursprungscodes bitte unterlassen). Und mit der neusten C#-Version kann man "ältere"Codeartefakte unterlassen und deren Hinzufügen dem Compiler überlassen.
Werde mich da mal umschauen. Habe mich extra an diese Community gewendet, weil man hier top Unterstützung bekommt. War im Java-Basics Forum immer der Fall.
 

Oben