Autor Beitrag
Calanthe
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 27.10.18 18:36 
Hallo Community,

ich habe folgendes Problem:
Ich soll alle dreistelligen Zahlen ausgeben lassen, die durch alle ihre Ziffern teilbar sind. So zum Beispiel bei 384, die durch 3, 8 und 4 teilbar ist.
Das soll mit einer Schleife passieren. Jetzt habe ich im Internet nur ein paar Ansätze gefunden, mit denen ich als Anfänger nicht viel anfangen kann.
Bei einem Beispiel soll eine Zahl, die vorher bekannt ist, in seine Einzelteile zerlegt werden. Irgendwie weiß ich, dass mir das hilfreich sein kann, ich weiß nur nicht inwiefern. Bei dieser Lösung wird die Zahl erst %10, dann %100 und dann %1000 gerechnet, um die einzelnen Stellen abzukapseln und in neue Variablen ablegen zu können.

Und dann gibt es noch einen Codeschnippsel, der eine Lösung meines Problems darstellt, den ich aber absolut nicht verstehe:

ausblenden C#-Quelltext
1:
2:
3:
bool dividesSelf(int i) { 
    return(i+"").All(d=>i%(d-48d)<1);
}



Über Anregungen, die mich zur Lösung führen, wäre ich sehr dankbar


Moderiert von user profile iconTh69: Topic aus Alle Sprachen - Alle Plattformen verschoben am So 28.10.2018 um 08:45
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: Sa 27.10.18 22:23 
Zunächst einmal zur Erklärung der Methode dividesSelf. Zuvor allerdings meine Meinung zu diesem Schnippsel:

Meiner Meinung nach ist diese Möglichkeit für einen Anfänger völlig ungeeignet. Ich weiß zwar nicht wie weit dein Fortschritt in C# bisher aussieht, aber solltest du nach meiner Erklärung diese Methode ohne googeln nicht oder nur teilweise verstanden haben, rate ich dir eine andere Herangehensweise zu nehmen. Dazu aber später. Jetzt erstmal die Erklärung:

Grundlegend benutzt diese Methode die folgenden Inhalte:

1. String.Concat(...)
2. IEnumerable<char>
3. Lambda-Ausdrücke (lokale Funktionen)
4. Interpretation von chars als integer mittels Ascii-Tabelle

1. String.Concat(...)
Der erste Teil (i+"") führt eine Addition eines Integers mit einem String aus. Dabei wird intern die Methode String.Concat aufgerufen, welche die beiden zu addierenden Werte in Zeichenketten mittels der ToString-Methode umwandelt und aneinanderfügt. Das Ergebnis ist also ein String. Eine Addition eines integers mit einem leeren String ist gleichzusetzen mit integer.ToString.

2. IEnumerable<char>
Ein String ist in C# eine Liste an chars. Die Basis von fast jeder Liste (BITTE KORRIGIERT MICH, WENN DIES FALSCH IST) bildet das Interface IEnumerable<>, in diesem Fall IEnumerable<char> (vom Typ char).

3. Lambda-Ausdrücke (lokale Funktionen)
Die Funktion All bestimmt, ob alle Elemente in einer Sequenz eine bestimmte Bedingung erfüllen. Diese Bedingung wird mittels einer lokalen Funktion, einem Lambda-Ausdruck definiert und geprüft. Wie gesagt werden Lambda-Ausdrücke auch lokale oder anonyme Funktionen genannt. Dies sind Funktionen die nicht vor ihrem Aufruf auf die übliche Art und Weise definiert werden müssen und man kann Lambda-Ausdrücke in sogenannten Delegaten speichern.

Lambda-Ausdrücke haben wie normale Funktionen auch Eingabeparameter und einen Rückgabewert. Die Eingabeparameter werden links vom 'Lambda-Operator (=>)' angegeben. Der Rückgabewert ergibt sich aus dem Term rechts vom Opertator. Man sagt: 'Die Eingabeparameter werden abgebildet auf den Term ...'. In unserem Fall ist der Eingabe-Parameter ein char, nämlich der char, der momentan auf die Bedingung geprüft wird, und heißt d. 'd' wird abgebildet auf einen booleschen Vergleich, das bedeutet, dass der Rückgabewert ein boolescher Wert ist. Wenn für jedes Element der Sequenz der Ausdruck true zurückgibt, dann gibt All den Wert true zurück, was bedeutet, das alle Elemente die Bedingung erfüllen

4. Interpretation von chars als integer mittels Ascii-Tabelle
Kommen wir zu der eigentlichen Bedingung. Hierbei wird der Modulo, also der Rest bei einer ganzzahligen Division berechnet. Für uns muss gelten, dass der Modulo für jede Division durch die einzelnen Ziffern 0 ist. Unsere Ziffern liegen im Moment allerdings noch als Chars vor. Wir müssen also die Chars in integer umwandeln. Hierbei hilft der Ascii-Code. In der Ascii-Tabelle stehen die Ziffern 0-9 an den Positionen 48-57. Wenn wir einen char mittels Casting in einen integer umwandeln, werden allerdings nicht die Werte 0-9 sondern die Werte 48-57 ausgegeben. Wir müssen danach also noch 48 abziehen. Dadurch wird aus der 48 eine 0 und aus der 57 eine 9. Da bei einer Addition oder Subtraktion, bei der ein char und ein int beteiligt sind, bereits mit dem Ascii-Wert des Chars gerechnet wird, müssen wir am Ende kein Casting mehr durchführen, da der Ergebnistyp bereits ein int ist.






Grobe Zusammenfassung
Wir wandeln einen integer in eine Liste an Chars um (die einzelnen Ziffern) und prüfen ob unsere Ausgangszahl ganzzahlig durch unser zu ints convertierten Ziffern teilbar ist. Wenn ja wird true zurückgegeben, wenn nein false

Hilfreiche Links:
stackoverflow.com/qu...ts-behind-the-scenes
docs.microsoft.com/d...s/lambda-expressions
docs.microsoft.com/d...tors/lambda-operator
www.torsten-horn.de/techdocs/ascii.htm
docs.microsoft.com/d...w=netframework-4.7.2
docs.microsoft.com/d...ing-guide/delegates/


Leichterer Ansatz für Anfänger
www.tutorials.de/thr...ahl-auslesen.316333/ Antwort von SGSSGene.
bole
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 105
Erhaltene Danke: 9

win 7
Turbo Delphi 2006
BeitragVerfasst: Sa 27.10.18 23:11 
Hallo Kasko

Hast Du auch gesehen woher dieser Code Schnipsel kommt? codegolf.stackexchan...mp;tab=votes#tab-top

Da geht's darum diese Funktion möglichst kurz umzusetzen, die verständdlichkeit ist nicht das Ziel :wink: :)

Als Spielerei sicher interessant...

Gruss

Bole

_________________
ein programm macht nicht das was du willst sondern was du schreibst!
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 27.10.18 23:12 
Danke Kasko für die Erklärung, die auch durchaus verständlich war, aber mein Können (noch) deutlich übersteigt.
Zu meinem Problem noch eine Frage:
Kann ich meine jetzigen Ansätze mal dazu packen und ihr sagt mir, wie weit ich von der Lösung entfernt bin?
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: Sa 27.10.18 23:18 
Klar doch. Dafür ist ein Forum doch da ;)
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: Sa 27.10.18 23:32 
Im Idealfall ist es so, richtig :wink:

Also, soweit bin ich gekommen:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
int zahl, temp, ziffer1, ziffer2, ziffer3;
            for(zahl=100; zahl<1000; zahl++)
            {
                if (zahl % 10 != 0)
                {
                    temp = zahl % 10;
                    ziffer1 = temp;

                    zahl = zahl - temp;
                    temp = zahl % 100;
                    ziffer2 = temp / 10;

                    zahl = zahl - temp;
                    temp = zahl % 1000;
                    ziffer3 = temp / 100;
                }

            }


Nun hängt es noch am Beenden der Schleife. Kann sein, dass ich gerade auch nur einfach mörderlich auf dem Schlauch steh :?
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: Sa 27.10.18 23:59 
Zunächst einmal würde ich dir raten die 'Überprüfung auf mögliche Division durch die Ziffern' und die 'for-schleife für alle 3-stelligen Zahlen' in zwei verschiedene Methoden zu separieren.

Zudem musst du die Bedingung in deiner If-Anweisung anpassen, da sie nicht immer korrekte Entscheidungen trifft. Z.B. bei der Zahl 730 tritt der if-Zweig nicht in Kraft und du gehst wahrscheinlich davon aus, dass die Zahl dann teilbar ist, was hier z.B. aber nicht der fall ist. Korrekt wäre sie nur wenn du den Modulo mit einer Potenz von 10 berechnest, welche die selbe Anzahl an Ziffern hat, wie der maximale Wert den du prüfen möchtest. Hier also Modulo 100. Da dies dann immer nur in 10 Fällen eintritt, geht die Chance Rechenleistung zu sparen bei großen Werten fast gegen 0, also kannst du sie auch theoretisch weglassen.

Die Ziffernauslese ist aber total korrekt ;) Du musst nun also nur noch schauen ob die Zahl durch alle ihre Ziffern, die du bereits ausgelesen hast, ganzzahlig teilbar ist und wenn ja kannst du die Zahl ausgeben. Das Problem ist aber, dass du die Ausgangszahl veränderst und du nach der Auslese nicht mehr dividieren kannst, weil die Zahl verfremdet wurde. Zudem bringst du deine for-Schleife durcheinander weil du ihre Zählvariable veränderst, was möglicherweise sogar in einer Endlosschleife endet.




Die Frage ist jetzt, welche Hilfe du erwartest. Möchtest du, dass wir dich in die richtige Richtung schubsen, sodass du die Lösung selber finden musst und der AHA-Effekt deutlich größer ist, oder möchtest du z.B. von mir eine Beispielimplementierung haben (natürlich mit den, dir zur Verfügung stehenden Mitteln) und du schaust war ich/wir anders gemacht haben?


Zuletzt bearbeitet von Kasko am So 28.10.18 01:27, insgesamt 3-mal bearbeitet
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 28.10.18 00:08 
Auf die Idee bin ich schon gekommen, allerdings besteht da dann das Problem, dass ich noch nicht mit Methoden gearbeitet habe.

Natürlich tritt der if-Zweig dann nicht in Kraft, weil die Division durch 0 nicht gültig ist. Ich habe nur die Fälle noch vergessen, in denen die 0 an zweiter Stelle steht. Korrigier mich bitte, wenn ich dich falsch verstanden habe.

Wenn ich als Zählvariable einfach eine neue festsetze, funktioniert es dann immer noch?
Also statt dem "zahl" in der Schleife einfach einen Buchstaben?
Und nehmen die Variablen "zifferx" ihre Werte auf der if-Anweisung mit raus, oder existieren diese Werte nur innerhalb?

Ich möchte in jedem Fall den Schubser haben, weil der Lerneffekt damit auch größer ist. Ich mag es nicht, wenn man mir Lösungen hinklatscht. Erst muss ich selbst überlegen und wenn ich gar nicht mehr weiter weiß, dann sag ich bescheid :)
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: So 28.10.18 00:24 
Zur Division durch 0:
Das kommt jetzt ganz darauf an, wie deine Aufgabe formuliert ist.

1. Division durch 0 ist nicht möglich und deshalb wird die Zahl nicht zur Ausgabe hinzugezählt.
2. Division durch 0 ist zwar nicht möglich wird aber ignoriert und es wird nur auf Ziffern geprüft, welche ungleich null sind. --> Meine Idee

Zur for-Schleife:
Richtig. Einfach einen anderen Namen für die Zählvariable wählen. Meist verwendet man i. Zahl dann immer am Anfang auf i setzen.


Ausgabe in die Console solltest du hinbekommen ;)



P.S.:

Ich würde die if-Anweisung umkehren, da ich es persönlich nicht mag, wenn viele Anweisungen in der if stehen, aber das ist nur ein Bauchgefühl. Es ändert nichts und daher kann ich es dir ja zeigen ;)

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
for (zahl = 100; zahl < 1000; zahl++)
{
    if (zahl % 10 == 0)
        continue//---> mit dem nächsten Zähler der Schleife weitermachen und Rest ignorieren

    temp = zahl % 10;
    ziffer1 = temp;

    zahl = zahl - temp;
    temp = zahl % 100;
    ziffer2 = temp / 10;

    zahl = zahl - temp;
    temp = zahl % 1000;
    ziffer3 = temp / 100;

    // Dein Part
}


Extra nichts anderes verändert ;)


Zuletzt bearbeitet von Kasko am So 28.10.18 12:27, insgesamt 1-mal bearbeitet
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 28.10.18 00:47 
Das ist der aktuelle Stand:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
int temp, zahl, ziffer1, ziffer2, ziffer3;
            for (int i = 100; i < 1000; i++)
            {
                if (i % 10 != 0)
                {
                    zahl = i;
                    temp = zahl % 10;
                    ziffer1 = temp;

                    zahl = zahl - temp;
                    temp = zahl % 100;
                    ziffer2 = temp / 10;

                    zahl = zahl - temp;
                    temp = zahl % 1000;
                    ziffer3 = temp / 100;

                    if (zahl % ziffer1 == 0 && zahl % ziffer2 == 0 && zahl % ziffer3 == 0)
                    {
                        Console.WriteLine(zahl);
                    }
                }    
            }


Ich habe versucht, "continue" einzufügen und die Anweisung zu drehen, aber dann sagt er mir, der Rest sei unerreichbarer Code. Woran liegt das?

Und wenn ich das so versuche, in der Console anzeigen zu lassen, kommt die Fehlermeldung, dass eine Division mit 0 versucht wurde und das nicht geht.

Ich setze mich morgen nochmal dran und denke in vollkommen wachem Zustand darüber nach :lol:

[Edit]: Und schön sehen die beiden verschachtelten if-Anweisungen auch nicht aus!
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: So 28.10.18 00:57 
Jap z.B. bei der Zahl 101 tritt dies auf. Der if Zweig wird aufgerufen, weil ein Rest von 1 bleibt, aber die zweite Ziffer ist eine 0. Und ich glaube du hast einfach bei der if Anweisung vergessen die Klammern zu entfernen, wodurch nach dem continue und innerhalb der Anweisung noch etwas folgte. Deshalb Klammern weg dann gehört nur die erste Anweisung zum if.

Lass die erste if einfach weg und prüfe auf 0 woanders.
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 28.10.18 13:40 
So. Ich dachte, ich hätte einen Geistesblitz gehabt, bei euch werden sich aber wohl die Nackenhaare aufstellen..

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
int temp, zahl, ziffer1, ziffer2, ziffer3;
            for (int i = 100; i < 1000; i++)
            {
                zahl = i;
                temp = zahl % 10;
                ziffer1 = temp;

                zahl = zahl - temp;
                temp = zahl % 100;
                ziffer2 = temp / 10;

                zahl = zahl - temp;
                temp = zahl % 1000;
                ziffer3 = temp / 100;

                
                if (ziffer1 != 0 && ziffer2 != 0 && ziffer3 != 0)
                {
                    if (zahl % ziffer1 == 0 && zahl % ziffer2 == 0 && zahl % ziffer3 == 0)
                    {
                        Console.WriteLine(zahl);
                    }
                }
            }


Ernüchtert stellte ich fest, dass er mir jetzt nur 100, 200, 300, 400, 500, 600, 700, 800, 900 ein paar Mal ausgibt. Ich weiß auch, dass es daran liegt, weil ich nicht prüfen lasse, ob die zahl durch 10 teilbar ist, bevor ich die Ziffern auslese. Aber ich hab ehrlich keine Ahnung, wie ich das davor abfragen soll, ohne endlos if-Anweisungen zu schachteln..
Ralf Jansen
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 4369
Erhaltene Danke: 882


VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
BeitragVerfasst: So 28.10.18 14:03 
Deine zu prüfende Zahl steht in der Variable i nicht in zahl.

Da du so überrascht tust über das Ergebnis scheint mir das du dich im Moment noch vom Endergebnis deines Codes überraschen lässt. Starte deinen Code im Debugger und beobachte Schritt für Schritt was er tut. Dabei wird die die Erkenntnis was dein Code macht quasi um die Ohren gehauen. Die Console beobachten, Code ändern, Console beobachten etc. ist unglaublich ineffektiv und kaum lehrreich für dich. Lerne debuggen, also wie setzte ich eine Breakpoint im Code, wie sehe ich den Inhalt einer Variablen während der Code steht, wie führe ich den Code dann Schrittweise weiter etc. Wenn du das verstanden hast werden sich deine Problem ruck zuck von dir selbst lösen lassen. Danach können wir dann gemeinsam überlegen wie sich der dann funktionierende Code noch verbessern lässt. (Besser im Gegensatz zu dem gezeigten Codegolf-Zeugs).

Für diesen Beitrag haben gedankt: Calanthe
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 28.10.18 14:24 
Hi Ralf,

ja, ich lasse mich mehr oder weniger überraschen davon, was rauskommt. Leider habe ich nicht mehr allzu viel Zeit, das Projekt abzugeben und deswegen auch keine Zeit mehr, herauszufinden, wie ich den Debugger benutze.
Aber deinen Rat werde ich befolgen und mich bei nächster Gelegenheit mal damit auseinandersetzen.
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: So 28.10.18 15:23 
Eigentlich unterstütze ich die Meinung von @Ralf Jansen, aber
Zitat:
Leider habe ich nicht mehr allzu viel Zeit, das Projekt abzugeben


Daher hier die Erklärung von den Vorgängen, die du durch Debugging selbst erkennen würdest. Obwohl es nicht sehr lange dauert sich mit den Basics beim Debugging vertraut zu machen. Höchstens ne Stunde.

Also, um die einzelnen Ziffern auszulesen rechnest du ja den Modulo mit einer 10er Potenz aus (% 10 ^ Stelle der Ziffer). Den Rest ziehst du von der Zahl ab und beim Rest entfernst du durch Division alle rechts stehenden Nullen.

Folgendes läuft ab:

zahl = 632;
temp = 632 % 10 = 2;
ziffer1 = 2 --> hat keine rechts stehenden Nullen also ist das die Ziffer

Divisor vom Modulo und 'Nullen entfernen' mal Zehn rechnen

zahl = 632 - 2 = 630;
temp = 630 % 100 = 30;
ziffer2 = 30 / 10 = 3 --> Ziffer

Divisor vom Modulo und 'Nullen entfernen' mal Zehn rechnen

zahl = 630 - 30 = 600;
temp = 600 % 1000 = 600;
ziffer3 = 600 / 100 = 6 --> Ziffer

Nun wurde deine Zahl aber wieder verfremdet. Zahl ist jetzt immer ein vielfaches von 100, deshalb wird dir auch nur das ausgegeben.

Wie @Ralf Jansen schon gesagt, hat steht deine zu prüfende Zahl in i also muss diese Variable in die ifs integriert werden. Und noch ein kleiner Tipp. Lass bei ifs mit nur einer inneren Anweisung die Klammern weg. Sieht einfach angenehmer aus.

ausblenden C#-Quelltext
1:
2:
3:
if (ziffer1 != 0 && ziffer2 != 0 && ziffer3 != 0)
    if (zahl % ziffer1 == 0 && zahl % ziffer2 == 0 && zahl % ziffer3 == 0)
        Console.WriteLine(zahl);
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 28.10.18 17:06 
Ich hatte mich jetzt nochmal dran gesetzt, weil es mich gewurmt hat, dass ich meinen Fehler nicht erkannt hatte. Was das Debugging angeht, hatte ich mich nochmal soweit eingelesen, dass ich endlich erkannt habe, wo der Fehler liegt und ihn beheben konnte.
Deine Erklärung, Kasko, hätte mir zwar geholfen, aber ich wollte selbstständig noch drauf kommen, weshalb ich auch erst jetzt nochmal ins Forum reinschaue.
Hier also die endgültige Version, die auch läuft und tut, was sie soll:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
int temp, ziffer1, ziffer2, ziffer3, umbruch = 0;
            for (int zahl = 100; zahl < 1000; zahl++)
            {
                ziffer1 = zahl % 10;
                ziffer2 = (zahl % 100) / 10;
                ziffer3 = (zahl % 1000) / 100;
                
                if (ziffer1 != 0 && ziffer2 != 0 && ziffer3 != 0)
                {
                    int temp1 = zahl % ziffer1;
                    int temp2 = zahl % ziffer2;
                    int temp3 = zahl % ziffer3;

                    if (temp1 == 0 && temp2 == 0 && temp3 == 0)
                    {
                        Console.Write("{0,4}", zahl);
                        umbruch++;

                        int tempUmbruch = umbruch % 12;
                        if (tempUmbruch == 0)
                            Console.Write("\n");
                    }
                }
            }


Die Formatierungen sind nur, damit die Ausgabe schöner aussieht.

Verbesserungsvorschläge zur Schönheit des Codes nehme ich gerne an.

Und vielen, vielen Dank für die Hilfe an euch.
lapadula
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 167
Erhaltene Danke: 10



BeitragVerfasst: So 28.10.18 17:14 
Vielleicht so?

Die Zahl wird zuerst zerlegt, die Nullen rausgefilter und in einer List gespeichert.
Dann gehe ich die einzelnen Chars durch und wandele diesen erstmal in den numerischen Wert um.
Ergbit die Division einen Restwert, dann wird die Hilfsvariable auf false gesetzt und das Programm springt aus der Schleife.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
private void button1_Click_1(object sender, EventArgs e)
        {

            for (int i = 384; i < 1000; i++)
            {

                var charArr = i.ToString().ToArray();

                bool ist = true;

                foreach (var c in charArr)
                {
                    var zahl = Char.GetNumericValue(c);
                    if (i % zahl != 0)
                    {
                        ist = false;
                        break;
                    }
                }

                if (ist)
                {
                    MessageBox.Show(i.ToString());
                }
            }
        }


Zuletzt bearbeitet von lapadula am So 28.10.18 19:02, insgesamt 2-mal bearbeitet
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: So 28.10.18 17:54 
@lapadula

Dein Lösungsansatz mag auch fast korrekt sein aber er enthält genauso Lambda-Ausdrücke und Linq-Methoden, wie der Code-Schnippsel aus der Fragestellung. Daher ist er zwar etwas leichter zu verstehen aber man benötigt die selben Inhalte, welche nicht zum Wissen eines Anfängers gehören. Daher kann man auch gleich den Code-Schnippsel verwenden. Der ist deutlich kürzer.

Zudem ist dein Where-Prädikat nicht korrekt.

1. Du vergleichst den char mit dem WERT 0 nicht mit dem ZEICHEN 0. Dadurch vergleichst du eigentlich den char mit dem 0ten Zeichen der Ascii-Tabelle ('NUL').
2. Selbst wenn du jetzt mit dem Zeichen 0 vergleichst, wird dadurch keine 0 der Liste hinzugefügt. Dadurch wird zwar eine Division durch 0 verhindert aber dadurch wird das Ergebnis verfälscht, weil dann auch Zahlen wie 101 die Bedingungen erfüllen und ausgegeben werden, was nicht Sinn und Zweck der Aufgabe ist.

Zudem eine Anmerkung:
Dein boolescher Wert 'ist' wird niemals true, weil er am Anfang false ist und im Falle einer nicht möglichen ganzzahligen Division auch auf false gesetzt wird.



Hier eine Lösung, die Anfängerinhalte verwendet und trotzdem an eine dynamische Ziffernanzahl angepasst ist. Ich kann sie ja jetzt posten, da du (@Calanthe) deine Lösung ja jetzt gefunden hast ;) Schön zu sehen, dass du zudem erkannt hast, dass das ganze durch Verwendung der ganzzahligen Division verkürzt werden kann.

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
static void Main(string[] args) {
    for (int i = 100; i < 1000; i++)
        if (DividesSelf(i))
            Console.WriteLine(i);

    Console.ReadKey();
}

private static bool DividesSelf(int value) {
    int ziffer, divisor = 1, modDivisor = 10;

    for (int i = 0; i < value.ToString().Length; i++, divisor *= 10, modDivisor *= 10) {
        ziffer = (value % modDivisor) / divisor;

        if (ziffer == 0 || value % ziffer != 0)
            return false;
    }

    return true;
}


Zuletzt bearbeitet von Kasko am So 28.10.18 23:47, insgesamt 1-mal bearbeitet
Calanthe Threadstarter
Hält's aus hier
Beiträge: 9



BeitragVerfasst: So 28.10.18 18:05 
@lapadula

Das ist lieb gemeint, aber ich verstehe kein Wort von deinem Code. Das ist eindeutig noch nichts, was ich als Anfänger können könnte.

@Kasko

Deine Lösung ist für mich fast schlüssig. Nur hab ich noch keine Ahnung von Methoden. So weit fortgeschritten ist mein Studium noch nicht. Aber ich merke es mir vor, als Beispiel, wenn ich dann soweit bin :)
Vielen lieben Dank.
Kasko
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 71



BeitragVerfasst: So 28.10.18 18:32 
Dann danke mit dem thx-Button den Beträgen die dir geholfen haben, damit in Zukunft Leute, die das selbe Problem haben, anerkannte Lösungen finden.