Forum:  Programmieren
Thema: Programm bool justOnce(int feld[], int size)
Themen-Übersicht
Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Themenstart: 2020-11-21 17:07

Hallo, kann mir jemand Teile des Programms erklären?:





1. Wieso ist bei der ersten for-Schleife "i=0" und bei der zweiten for-Schleife "i=1"? Ich sehe den Grund nicht?

2. Was wird da gemacht: count[feld[i]]++;
Das ist ja ein Array. Wie soll ich das mit dem "++" dahinter verstehen?

Und: Was ist nicht in Ordnung bei der Implementierung:

#include <iostream>
 
using namespace std;
 
int justOnce(int *feld, int size);
 
int justOnce(int feld[], int size)
{
    if (size==-1) {feld[0] = -7; return false;}
    if (feld == NULL)
        throw runtime_error("nullptr not expected");
    int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    for (int i = 0; i < size; i++) {
        if (feld[i] <= 9 && feld[i] >= 1)
            count[feld[i]]++;
    }
    for (int i = 1; i < 10; i++) {
        if (count[i] != 1)
 
        return false;
    }
       return true;
    };
 
 
 
 
 



Liebe Grüße, Kajam


StrgAltEntf
Senior
Dabei seit: 19.01.2013
Mitteilungen: 6686
Herkunft: Milchstraße
Beitrag No.1, eingetragen 2020-11-21 18:08

2020-11-21 17:07 - Kajam im Themenstart schreibt:
1. Wieso ist bei der ersten for-Schleife "i=0" und bei der zweiten for-Schleife "i=1"? Ich sehe den Grund nicht?

2. Was wird da gemacht: count[feld[i]]++;
Das ist ja ein Array. Wie soll ich das mit dem "++" dahinter verstehen?

1. Warum sollte denn die erste Schleife erst bei 1 loslaufen oder die zweite Schleife schon bei 0?

2. count[feld[i]]++ ist gleichbedeutend mit count[feld[i]]=count[feld[i]]+1


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.2, vom Themenstarter, eingetragen 2020-11-21 19:02

1. Genau das vestehe ich nicht. Es müssen doch immer 9 Felder sein. Bei i=1 bis i<10 sind es 8 Felder. Wieso?

2. Heißt das jetzt, ich addiere einfach eine 1 zum Feld? Wenn z.B. der Wert vom ersten Feld 7 ist, dann habe ich 7+1=8? Was bringt das?


StrgAltEntf
Senior
Dabei seit: 19.01.2013
Mitteilungen: 6686
Herkunft: Milchstraße
Beitrag No.3, eingetragen 2020-11-21 19:12

2020-11-21 19:02 - Kajam in Beitrag No. 2 schreibt:
1. Genau das vestehe ich nicht. Es müssen doch immer 9 Felder sein. Bei i=1 bis i<10 sind es 8 Felder. Wieso?

2. Heißt das jetzt, ich addiere einfach eine 1 zum Feld? Wenn z.B. der Wert vom ersten Feld 7 ist, dann habe ich 7+1=8? Was bringt das?

1. Dann zähl noch mal nach ...

2. Das Feld count[i] zählt, wie oft der Wert i vorkommt. Für jedes Vorkommen von i wird count[i] um eins erhöht.


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.4, eingetragen 2020-11-21 20:21

2020-11-21 17:07 - Kajam im Themenstart schreibt:
1. Wieso ist bei der ersten for-Schleife "i=0" und bei der zweiten for-Schleife "i=1"? Ich sehe den Grund nicht?
Beachte, welches Array mit der jeweiligen Schleife durchlaufen wird.
Und dann überlege nochmal, warum mal bei 0 und in der anderen Schleife (Prüfung) bei 1 begonnen wird.

2020-11-21 17:07 - Kajam im Themenstart schreibt:
2. Was wird da gemacht: count[feld[i]]++;
Das ist ja ein Array. Wie soll ich das mit dem "++" dahinter verstehen?
Das ist eine in C[++] übliche Kurzschreibweise für
C++
zahl = feld[i];
count[zahl] = count[zahl] + 1;

Kajam schreibt:
Und: Was ist nicht in Ordnung bei der Implementierung:
Denn Fehler hattest du schon mal: es fehlt das main Hauptprogramm.

Und nochmal:
Bitte keine Screenshots!
Selbst aus einer PDF-Datei kann man den (Aufgaben)Text (meistens) rauskopieren und hier verwenden.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.5, vom Themenstarter, eingetragen 2020-11-21 20:35

1. Ich komme echt nicht drauf, wieso bei der zweiten Schleife "i=0" raus gelassen wird. Es müssten doch 10 Felder sein? Ich brauche mal mehr Hilfestellungen :(

2. Heißt das jetzt, dass wenn z.B "int[0]" und "int[1]" den gleichen Wert haben, der Ausdruck "int[0]+1" meint, dass der Wert, z.B "5" zwei mal vorkommt?

3. Muss die main-Funktion immer implementiert sein?
Und was fehlt da jetzt genau? Die Felder nicht? Die true- / und false-Ausgaben?


StrgAltEntf
Senior
Dabei seit: 19.01.2013
Mitteilungen: 6686
Herkunft: Milchstraße
Beitrag No.6, eingetragen 2020-11-21 22:12

2020-11-21 20:35 - Kajam in Beitrag No. 5 schreibt:
1. Ich komme echt nicht drauf, wieso bei der zweiten Schleife "i=0" raus gelassen wird. Es müssten doch 10 Felder sein? Ich brauche mal mehr Hilfestellungen :(

2. Heißt das jetzt, dass wenn z.B "int[0]" und "int[1]" den gleichen Wert haben, der Ausdruck "int[0]+1" meint, dass der Wert, z.B "5" zwei mal vorkommt?

3. Muss die main-Funktion immer implementiert sein?
Und was fehlt da jetzt genau? Die Felder nicht? Die true- / und false-Ausgaben?
1. Laut Aufgabenstellung sollen lediglich die zahlen von 1 bis 9 betrachtet werden. Deshalb ist die 0 raus gelassen.

2. Die Frage verstehe ich nicht. ("int[0]" ist in C oder C++ übrigens nicht erlaubt, da "int" reserviert ist für die Deklaration von ganzzahligen Variablen.)

3. Ja. Jedes lauffähige Programm benötigt eine main-Funktion.


dlchnr
Aktiv
Dabei seit: 20.04.2013
Mitteilungen: 192
Herkunft: Aalen, DE
Beitrag No.7, eingetragen 2020-11-21 23:22

Ich würde Dir raten, dass Du Dir ein ordentliches C++ Buch besorgst und die Sprache ordentlich von der Pike auf lernst!

Solche Sachen, wie in der ersten Zeile auf das erste Element eines Feldes zu schreiben und in der zweiten Zeile zu prüfen, ob der Pointer auf das Feld überhaupt gültig ist, dürfen nicht passieren ;-)

Bjarne Stroustrup schreibt in einem gut zu lesenden Englisch, drum nehm ich an, dass "Programming: Principles and Practice Using C++" zu empfehlen ist.


dlchnr
Aktiv
Dabei seit: 20.04.2013
Mitteilungen: 192
Herkunft: Aalen, DE
Beitrag No.8, eingetragen 2020-11-21 23:26

Eine weitere Anlaufstelle auch für andere Programmiersprachen:
programming-motherfucker.com/become.html


StrgAltEntf
Senior
Dabei seit: 19.01.2013
Mitteilungen: 6686
Herkunft: Milchstraße
Beitrag No.9, eingetragen 2020-11-21 23:37

2020-11-21 23:22 - dlchnr in Beitrag No. 7 schreibt:
Solche Sachen, wie in der ersten Zeile auf das erste Element eines Feldes zu schreiben und in der zweiten Zeile zu prüfen, ob der Pointer auf das Feld überhaupt gültig ist, dürfen nicht passieren ;-)
Dieser Fauxpas dürfte wahrscheinlich nicht vom Frage- sondern vom Aufgabensteller zu stammen.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.10, vom Themenstarter, eingetragen 2020-11-22 01:41

2020-11-21 22:12 - StrgAltEntf in Beitrag No. 6 schreibt:
2020-11-21 20:35 - Kajam in Beitrag No. 5 schreibt:
1. Ich komme echt nicht drauf, wieso bei der zweiten Schleife "i=0" raus gelassen wird. Es müssten doch 10 Felder sein? Ich brauche mal mehr Hilfestellungen :(

2. Heißt das jetzt, dass wenn z.B "int[0]" und "int[1]" den gleichen Wert haben, der Ausdruck "int[0]+1" meint, dass der Wert, z.B "5" zwei mal vorkommt?

3. Muss die main-Funktion immer implementiert sein?
Und was fehlt da jetzt genau? Die Felder nicht? Die true- / und false-Ausgaben?
1. Laut Aufgabenstellung sollen lediglich die zahlen von 1 bis 9 betrachtet werden. Deshalb ist die 0 raus gelassen.

2. Die Frage verstehe ich nicht. ("int[0]" ist in C oder C++ übrigens nicht erlaubt, da "int" reserviert ist für die Deklaration von ganzzahligen Variablen.)

3. Ja. Jedes lauffähige Programm benötigt eine main-Funktion.

1. Aber wieso ist die 0 raus und nicht die 9? Damit wäre es doch auch getan? Und in der ersten for-Schleife werden auch alle Indizies von i=0 bis i=9 gezählt? Wieso fängt man dann schon hier laut der Aufgabenstellung nicht die Zahlen von 1 bis 9 zu betrachten?

2. Es sollte kein Integer sein. Ich habe mich verschrieben. Es soll ein Array sein. Also array[0] oder wie in meinem Programmbeispiel Feld[0]. Jetzt stimmt die Aussage also?



Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.11, vom Themenstarter, eingetragen 2020-11-22 01:42

2020-11-21 23:22 - dlchnr in Beitrag No. 7 schreibt:
Ich würde Dir raten, dass Du Dir ein ordentliches C++ Buch besorgst und die Sprache ordentlich von der Pike auf lernst!

Solche Sachen, wie in der ersten Zeile auf das erste Element eines Feldes zu schreiben und in der zweiten Zeile zu prüfen, ob der Pointer auf das Feld überhaupt gültig ist, dürfen nicht passieren ;-)


Was ist daran schlimm/falsch? :P


Bjarne Stroustrup schreibt in einem gut zu lesenden Englisch, drum nehm ich an, dass "Programming: Principles and Practice Using C++" zu empfehlen ist.


dlchnr
Aktiv
Dabei seit: 20.04.2013
Mitteilungen: 192
Herkunft: Aalen, DE
Beitrag No.12, eingetragen 2020-11-22 02:53

2020-11-22 01:42 - Kajam in Beitrag No. 11 schreibt:


Was ist daran schlimm/falsch? :P


Das Niveau Deiner Fragen und das Niveau, das C++ an die Kompetenz eines Programmieres stellt, klaffen derart weit auseinander, dass ich Dir nur raten kann, das Ganze mit einem fundamental gesteigerten Engagement anzugehen oder zu einer einfacheren Progrmmiersprache, z.B. Python zu wechseln.


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.13, eingetragen 2020-11-22 10:14

2020-11-22 01:41 - Kajam in Beitrag No. 10 schreibt:

1. Aber wieso ist die 0 raus und nicht die 9? Damit wäre es doch auch getan? Und in der ersten for-Schleife werden auch alle Indizies von i=0 bis i=9 gezählt? Wieso fängt man dann schon hier laut der Aufgabenstellung nicht die Zahlen von 1 bis 9 zu betrachten?



Nimm ein einfaches Beispiel und gehe dieses Schritt für Schritt durch.
Der sogenannte "Bleistifttest" wurde ja schon dutzende Male angeraten und man hat das Gefühl, dass du das sehr konsequent ignorierst.
(Klausuren zu Einsteigervorlesungen in die Programmierung laufen übrigens auch mit Papier und Stift ab und erfordern ein selbständiges Lesen, Verstehen und Schreiben von Code.)


Schreibe den Algorithmus vielleicht auch einmal in Pseudocode auf und/oder kommentiere das Programm aus der Musterlösung Zeile für Zeile.
Was genau macht denn die erste Schleife und was ist Sinn und Zweck der zweiten Schleife?
Die Frage nach der $0$ wäre mit dieser kurzen Überlegung nämlich bereits beantwortet.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.14, vom Themenstarter, eingetragen 2020-11-22 14:53

2020-11-22 02:53 - dlchnr in Beitrag No. 12 schreibt:
2020-11-22 01:42 - Kajam in Beitrag No. 11 schreibt:


Was ist daran schlimm/falsch? :P


Das Niveau Deiner Fragen und das Niveau, das C++ an die Kompetenz eines Programmieres stellt, klaffen derart weit auseinander, dass ich Dir nur raten kann, das Ganze mit einem fundamental gesteigerten Engagement anzugehen oder zu einer einfacheren Progrmmiersprache, z.B. Python zu wechseln.

Ich muss nur das Modul "Programmieren in C++" durchziehen. Ich habe keine andere Wahl :)


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.15, vom Themenstarter, eingetragen 2020-11-22 15:19

2020-11-22 10:14 - DerEinfaeltige in Beitrag No. 13 schreibt:
2020-11-22 01:41 - Kajam in Beitrag No. 10 schreibt:

1. Aber wieso ist die 0 raus und nicht die 9? Damit wäre es doch auch getan? Und in der ersten for-Schleife werden auch alle Indizies von i=0 bis i=9 gezählt? Wieso fängt man dann schon hier laut der Aufgabenstellung nicht die Zahlen von 1 bis 9 zu betrachten?



Nimm ein einfaches Beispiel und gehe dieses Schritt für Schritt durch.
Der sogenannte "Bleistifttest" wurde ja schon dutzende Male angeraten und man hat das Gefühl, dass du das sehr konsequent ignorierst.
(Klausuren zu Einsteigervorlesungen in die Programmierung laufen übrigens auch mit Papier und Stift ab und erfordern ein selbständiges Lesen, Verstehen und Schreiben von Code.)


Schreibe den Algorithmus vielleicht auch einmal in Pseudocode auf und/oder kommentiere das Programm aus der Musterlösung Zeile für Zeile.
Was genau macht denn die erste Schleife und was ist Sinn und Zweck der zweiten Schleife?
Die Frage nach der $0$ wäre mit dieser kurzen Überlegung nämlich bereits beantwortet.

Ich ignoriere hier nichts. Die Tests mache ich auch, aber keine Besserung in Sicht. Hier mache ich das mal nochmal:
C++
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. int justOnce(int *feld, int size);
  6.  
  7. int justOnce(int feld[], int size)
  8. {
  9. if (size==-1) {feld[0] = -7; return false;} // Wenn size=-1, dann soll das nullte Feld den Wert -7 annehmen und "false" zurückgegeben werden.
  10.  
  11.  
  12. if (feld == NULL) // Wenn ein Feld den Wert NULL hat, wird das danach in Gänsefüßchen ausgegeben:
  13. throw runtime_error("nullptr not expected");
  14.  
  15. int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // Das verstehe ich nicht. Hier sind alle Werte der Felder gleich 0. Also wird das davor ausgeführt? Soll ich jetzt das davor mit den feld ==NULL(...) aus dem Programm entfernen oder die alle Felder nicht als den Wert 0 speichern?
  16.  
  17. for (int i = 0; i < size; i++) {
  18. if (feld[i] <= 9 && feld[i] >= 1) // Hier läuft eine Schleife von 0 bis 9, da size 10 ist. Hier verstehe ich nicht, ob sich das zwischen 9 und 10 auf den Wert der Felder oder auf den Index=i bezieht? Hier werden die Felder jedenfalls alle durchgegangen und geschaut, ob sich der Wert der Felder wiederholt? Wenn ja, wird die Anzahl der gleichen Felder um 1 erhöht?
  19.  
  20. count[feld[i]]++;
  21. }
  22.  
  23.  
  24.  
  25. for (int i = 1; i < 10; i++) {
  26. if (count[i] != 1)
  27.  
  28. return false;
  29. }
  30. return true;
  31. }; // In diesem letzten Teil läuft die Schleife von 1 bis 10. Demnach sind es 9 Felder, aber nicht 10, wie bei der ersten Schleife. Hier wird der Index i=0 ausgelassen. Wieso dieser und nicht ein anderer? Mit der if-Bedienung wird überprüft, ob count[i] nicht einmal gezählt wird. Falls ja, wird false ausgegeben. Demgegenüber wird ture ausgegeben, falls ein Element genau einmal vorkommt.
  32.  


Nun habe ich auch hier das Programm kommentiert. Wie man sieht, hat es nicht sonderlich geholfen und es sind noch paar Fragen dazu gekommen.
Wenn ich schon etwas nachfrage, dann weil ich wirklich nicht verstehe, und das nach dem Kopfzerbrechen darüber.
Über weitere Antworten/Hilfe zu diesen allen Unklarheiten wäre ich dankbar. Bis jetzt waren die Antworten auch gut, auch wenn sie mal länger dauern.🙃


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.16, eingetragen 2020-11-22 15:34

Poste deinen Bleistifttest doch einmal.
Welche Beispiele hast du denn konkret durchgerechnet und was ist in jedem Schritt passiert?


Deine Kommentare zum Code ergeben keinen Sinn.

Bspw. sagst du, dass bei der ersten Schleife diese von 0 bis 9 läuft.
Das stimmt im Allgemeinen nicht, da sie doch von 0 bis size-1 läuft.

Ein passender Kommentar dazu wäre:
C++
for (int i=0; i<size; i++){ // Iteriere über die Indizes von 0 bis size-1
  if (feld[i]>=1 && feld[i]<=9) // Falls feld[i] aus {1;2;...;9}, 
    count[feld[i]]++; // so erhöhe den entsprechenden Zähler um 1.
}


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.17, eingetragen 2020-11-22 16:55

Ich habe mal das Programm in Beitrag #15 lesbar gemacht (C++ Code) und die Numerierung eingefügt (dann kann man sich auf konkrete Zeilen beziehen).

DerEinfaeltige hat es ja schon angedeutet: Das Programm ist (zum Teil) Unsinn, die Kommentare falsch.

Zuallererst:
Deine Einrückungen sind eine Katastrophe um machen das Programm extrem schwer lesbar (und das ist nur ein winziges Progrämmelchen)😖

Zeilen 5 und 7
Du hast das vorgegeben Programm aus dem Themenstart verändert. Statt boolean gibst du nun int zurück. Was dann direkt im Widerspruch zum return false; in Zeile 9 steht.

Zeile 9
Die Zuweisung zum Feldelement [0] macht keinen Sinn, wenn erst später (in Zeile 12) festgestellt wird, ob überhaupt ein Feld übergeben wurde. Aber der Stuß steht ja schon so im Vorgabeprogramm😡
Der Kommentar ist zwar nicht falsch, aber sinnlos, denn das kann jeder sofort am Code erkennen.
Kommentare sind dazu da, die Logik zu erläutern, warum etwas gerade so gemacht wird. Oder um Variablen und deren Verwendung/Sinn zu erläutern.

Zeile 12
Der Kommentar ist Quatsch. „Wenn ein Feld den Wert NULL hat“ hat mit if (Feld == NULL) nichts zu tun. Es wird geprüft, ob überhaupt ein Pointer auf ein Feld übergeben wurde, d.h. ob überhaupt ein Feld vorhanden ist, das benutzt werden kann.
Insofern gehört diese Prüfung schon mal vor Zeile9!
wird das danach in Gänsefüßchen ausgegeben“ Hier fehlt mir ein Icon, wo sich der Smiley mit der Hand an die Stirn klatscht😲 Was ist das für ein Kindertext? Und ausgegeben wird gar nix, sondern eine Exception geworfen (throw), die in der übergeordneten Funktion (also dem Aufrufer) abzuhandeln ist.

Zeile 15
Es wird ein Feld count mit 10 Elementen angelegt, die alle mit 0 initialisiert werden. Sinnvoller Kommentar wäre:
C++
int count[10] = {...}; // Zähler für die Häufigkeiten der Zahlen 1..9
                       // count[0] ist eigentlich überflüssig, da die 0 nicht gezählt wird
                       // aber Felder beginnen nun mal in C++ immer mit dem Index 0

Zeilen 17–20
Siehe Beitrag #16

Zeile 31
In diesem letzten Teil läuft die Schleife von 1 bis 10. Demnach sind es 9 Felder, aber nicht 10, wie bei der ersten Schleife. Hier wird der Index i=0 ausgelassen. Wieso dieser und nicht ein anderer? Mit der if-Bedienung wird überprüft, ob count[i] nicht einmal gezählt wird. Falls ja, wird false ausgegeben. Demgegenüber wird ture ausgegeben, falls ein Element genau einmal vorkommt.
Unsinn3 😲
Hier noch mal der Code von Zeile 25..29 (und mit sinnvoller Einrückung)
C++
  1. for (int i = 1; i < 10; i++) {
  2. if (count[i] != 1)
  3. return false;
  4. }
• Die Schleife läuft von 1 bis 9 (i < 10)
• Sie startet bei 1, weil die 0 ja nicht gezählt wurde
• Wenn der Zähler für die Zahl i nicht genau 1 ist, dann
return false; // die Funktion wird vorzeitig verlassen (siehe Aufgabenstellung)

Zeilen 30,31
C++
  1. return true;
  2. }
Die Z.30 hat mit der Schleife davor rein gar nichts zu tun, denn diese ist mit Zeile 28 abgeschlossen.
return true; ist vielmehr der Abschluß der Funktion justOnce und gibt wahr zurück, weil nicht schon vorher (nämlich in Zeile 27) mit falsch abgebrochen wurde. Dieses true besagt genau das, was die Aufgabenstellung verlangt, nämlich daß jede der Zahlen 1..9 exakt 1× in Feld vorkommt.

2020-11-22 14:53 - Kajam in Beitrag No. 14 schreibt:
Ich muss nur das Modul "Programmieren in C++" durchziehen. Ich habe keine andere Wahl :)
Da spricht so richtig deine Begeisterung für's Programmieren🤔
Es wurde dir schon mehrfach angeraten: nimm dir ein vernünftiges Tutorial/Buch und arbeite es ordentlich durch. Du kannst auch nicht nach Japan fahren wenn du nur zwei Worte "hai" und "iie" gelernt hast.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.18, vom Themenstarter, eingetragen 2020-11-23 17:18

Ich verstehe immer noch nicht, wieso feld[0] nicht (mit)gezählt wird. In feld[0] ist doch auch eine Zahl als Wert gespeichert. Man übersieht doch eine Zahl in meinen Augen!

Dieser Teil*:

for (int i=0; i<size; i++){ // Iteriere über die Indizes von 0 bis size-1
  if (feld[i]>=1 && feld[i]<=9) // Falls feld[i] aus {1;2;...;9},
    count[feld[i]]++; // so erhöhe den entsprechenden Zähler um 1.
}


*stellt für mich ein Wiederspruch zu diesem Teil dar:

for (int i = 1; i < 10; i++) {
   if (count[i] != 1)
      return false;
   }

Denn beim ersten Teil passiert folgendes:
Sagen wir, wie haben feld[9]={1, 2, 3, 4, 5, 6, 7, 8, 9}
Hier kommt jede Zahl genau einmal vor!
Also wird hier jedes mal der entsprechende Zähler um 1 erhöht.
Dabei wird der Zähler ja durchgehend +1 genommen. Zählt man es alles zusammen, ist es +9 mal. Das heißt, hier wird return false ausgeführt, wiewohl jede Zahl genau 1 mal vorkommt.

Ich verstehe das alles einfach nicht...ich heule gleich.
Deswegen habe ich keine Begeisterung für das Programmieren.
Ich frage mich, wer denkt sich sowas aus und wo kann es mir Leben helfen xD





StrgAltEntf
Senior
Dabei seit: 19.01.2013
Mitteilungen: 6686
Herkunft: Milchstraße
Beitrag No.19, eingetragen 2020-11-23 17:52

2020-11-23 17:18 - Kajam in Beitrag No. 18 schreibt:
Also wird hier jedes mal der entsprechende Zähler um 1 erhöht.
Dabei wird der Zähler ja durchgehend +1 genommen. Zählt man es alles zusammen, ist es +9 mal. Das heißt, hier wird return false ausgeführt, wiewohl jede Zahl genau 1 mal vorkommt.
Es wird ja jedes mal ein anderer Zähler erhöht. Für i=0 wird der Zähler count[1] erhöht (weil in feld[0] eine 1 steht), für i=1 wird der Zähler count[2] erhöht (weil in feld[1] eine 2 steht) usw.


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.20, eingetragen 2020-11-23 18:08

2020-11-23 17:18 - Kajam in Beitrag No. 18 schreibt:

*stellt für mich ein Wiederspruch zu diesem Teil dar:


Der Widerspruch ist, dass du behauptest, einen Bleistifttest durchgeführt zu haben, dann aber solche Fragen stellst.


Zwei kurze Bleistifttests:

Fall b)
feld={1,1,2} und size = 3

Vorbereitung:
count wird auf {0,0,0,0,0,0,0,0,0,0} gesetzt.

Erste Schleife:
 i = 0:
  feld[0] = 1 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[0]] ≡ count[1] wird erhöht
  count ist jetzt {0,1,0,0,0,0,0,0,0,0}
 i = 1:
  feld[1] = 1 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[1]] ≡  wird erhöht
  count ist jetzt {0,2,0,0,0,0,0,0,0,0}
 :
  feld[2] = 2 ⇒ if(2>=1 && 2<=9) erfüllt
  count[feld[2]] ≡ count[2] wird erhöht
  count ist jetzt {0,2,1,0,0,0,0,0,0,0}
 i = 3: Schleife bricht ab

Zweite Schleife:
 i = 1:
  count[1] = 2 != 1 ⇒ Rückgabe false


rlk
Senior
Dabei seit: 16.03.2007
Mitteilungen: 10975
Herkunft: Wien
Beitrag No.21, eingetragen 2020-11-23 18:22

Hallo Kajam,
feld[0] wird sehr wohl mitgezählt, deshalb läuft die erste Schleife ja von i = 0 bis i = size - 1.
Weil aber nur die Ziffern 1..9 gezählt werden sollen, wird nur für diese der entsprechende Zähler erhöht.

Der Zähler count[0] enthält daher keinen interessanten Wert und wird deshalb nicht ausgegeben. Das ist der Grund, warum die zweite Schleife mit i = 1 beginnt.

Versuche mit Deinen eigenen Worten zu erklären, welche unterschiedlichen Rollen die Variablen i in den beiden Schleifen spielen.

2020-11-23 17:18 - Kajam in Beitrag No. 18 schreibt:
Ich verstehe das alles einfach nicht...ich heule gleich.
Deswegen habe ich keine Begeisterung für das Programmieren.
Ich frage mich, wer denkt sich sowas aus und wo kann es mir Leben helfen xD
Du verstehst noch nicht alles, aber mit etwas Geduld und Mühe wird es Dir gelingen. Der Computer deckt Denkfehler gnadenlos auf, das kann manchmal frustrierend sein, aber die Beschäftigung kann Dir helfen, klarer zu denken und zu formulieren, was im Leben sicher nützlich ist.

Viel Erfolg wünscht Dir
Roland

[Die Antwort wurde nach Beitrag No.19 begonnen.]


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.22, eingetragen 2020-11-23 19:18

Da du anscheinend immer noch nicht den Unterschied der beiden Schleifen erkennst:

erste Schleife
i durchläuft das ganze Feld und zählt dabei in count, welche Zahl aus Feld wie oft vorkommt.

zweite Schleife
Hier werden die aufgelaufenen Zähler in count geprüft, und zwar für die Indizes 1..9, da die 0 nicht interessiert.
Ist einer der Zähler bei dieser Prüfung ≠1 (er steht noch auf 0 weil die Zahl gar nicht in Feld vorkommt oder er ist >1 weil die Zahl mehr als 1× vorkommt), dann stoppt Zeile 27 die Prüfung, indem die Funktion justOnce mit dem Return-Code false verlassen wird.
Waren alle Zähler wie gewünscht =1 (die zweite Schleife wurde regulär beendet), dann meldet die Funktion dies mit return true; an das aufrufende Programm zurück.
Das kann dann mit dieser Information (false bzw. true) machen, was es will.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.23, vom Themenstarter, eingetragen 2020-11-24 12:33

Ich habe das Prinzip verstanden. Ich möchte nun, dass mir ture oder false ausgegeben wird. Es wird mir bei dem folgenden Programm immer true ausgegeben. Woran liegt das?

#include <iostream>
 
using namespace std;
 
bool justOnce(int *feld, int size);
 
bool justOnce(int feld[], int size)
{
    if (size==-1) {feld[0] = -7; return false;}
    if (feld == NULL)
        throw runtime_error("nullptr not expected");
    int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    for (int i = 0; i < size; i++) {
        if (feld[i] <= 9 && feld[i] >= 1)
            count[feld[i]]++;
    }
    for (int i = 1; i < 10; i++) {
        if (count[i] != 1){
        cout << "false" << endl;
        return false;
        }
 
    else {
        cout << "true" << endl;
    }
    return true;
    };
}
    int main() {
    int feld[9] = {1, 2, 3, 9, 5, 6, 7, 8, 9,};
    justOnce(feld, 9);
    return 0;
 
    }


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.24, eingetragen 2020-11-24 12:57

Formatiere den Code vernünftig und es ist SOFORT klar, warum das nicht funktionieren kann.

Alternativ führe den Bleistifttest durch. (insbesondere Schritt für Schritt die zweite Schleife!)


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.25, vom Themenstarter, eingetragen 2020-11-24 15:44

Ich weiß nicht, was du mit dem Formatieren meinst.
Aber hier der Test:

feld={1,2,3,9,5,6,7,8,9} und size = 9

Vorbereitung:
count wird auf {0,0,0,0,0,0,0,0,0,0} gesetzt.

Erste Schleife:
 i = 0:
  feld[0] = 1 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[0]] ≡ count[1] wird erhöht
  count ist jetzt {0,1,0,0,0,0,0,0,0,0}

 i = 1:
  feld[1] = 2 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[1]] ≡  wird erhöht
  count ist jetzt {0,1,1,0,0,0,0,0,0,0}

 i = 2:
  feld[2] = 3 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[2]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,0,0,0,0,0,0}

 i = 3:
  feld[3] = 9 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[3]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,0,0,0,0,0,1}

 i = 4:
  feld[4] = 5 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[4]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,1,1,0,0,0,1}

 i = 5:
  feld[5] = 6 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[5]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,1,1,1,0,0,1}

 i = 6:
  feld[6] = 7 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[6]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,1,1,1,1,0,1}

 i = 7:
  feld[7] = 8 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[7]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,1,1,1,1,1,1}

 i = 8:
  feld[8] = 9 ⇒ if(1>=1 && 1<=9) erfüllt
  count[feld[8]] ≡  wird erhöht
  count ist jetzt {0,1,1,1,1,1,1,1,1,2}

Zweite Schleife:
 i = 1:
  count[1] = 1 != 1 ⇒ Rückgabe true
...

i=9
  count[9] = 2 != 1 ⇒ Rückgabe false


Und nun?
Es müsste false zurückgegeben werden.
Wieso tut es es nicht?


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.26, vom Themenstarter, eingetragen 2020-11-24 17:24

2020-11-23 19:18 - viertel in Beitrag No. 22 schreibt:
Da du anscheinend immer noch nicht den Unterschied der beiden Schleifen erkennst:

erste Schleife
i durchläuft das ganze Feld und zählt dabei in count, welche Zahl aus Feld wie oft vorkommt.

zweite Schleife
Hier werden die aufgelaufenen Zähler in count geprüft, und zwar für die Indizes 1..9, da die 0 nicht interessiert.
Ist einer der Zähler bei dieser Prüfung ≠1 (er steht noch auf 0 weil die Zahl gar nicht in Feld vorkommt oder er ist >1 weil die Zahl mehr als 1× vorkommt), dann stoppt Zeile 27 die Prüfung, indem die Funktion justOnce mit dem Return-Code false verlassen wird.
Waren alle Zähler wie gewünscht =1 (die zweite Schleife wurde regulär beendet), dann meldet die Funktion dies mit return true; an das aufrufende Programm zurück.
Das kann dann mit dieser Information (false bzw. true) machen, was es will.

Das Programm führt intern false oder true aus? Wenn ich es ausführe, kriege ich nichts angezeigt, ist das richtig? Wie kann ich das Programm so ändern, dass ich selbst sehe, ob es true oder false ist?


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.27, vom Themenstarter, eingetragen 2020-11-24 17:30

Nie funktioniert etwas bei mir...Wo muss ich etwas ausgeben, in der main-Funktion oder in der bool-Funktion? Und wie?


piteo
Aktiv
Dabei seit: 12.09.2014
Mitteilungen: 25
Beitrag No.28, eingetragen 2020-11-24 18:07

schon bei i=4 stimmt es nicht: count[4] wird nämlich nicht erhöht, sondern count[5], da feld[4] ja den Wert 5 hat. count sieht danach also so aus:
{0,1,1,1,0,1,0,0,0,1}

Die Aufgabenstellung lautet: justOnce gibt true zurück, wenn ...
und nicht: justOnce gibt "true" aus, wenn ...
Aus der Funktion müssen also alle cout-Ausgaben raus.

Wenn Du true ausgeben willst, wenn ..., dann musst Du im main-Programm den Rückgabewert der Funktion justOnce ausgeben, z.B. so:

cout << justOnce(feld, 9) << endl

Es wäre doch schade, wenn die Freude am Programmieren sich nicht irgendwann einstellt.

Und was der Ein... mit Formatierung meint:
das "else", hinter dem "true" ausgegeben wird, steht unter "for", deshalb meint man, es kommt erst nach der for-Schleife.
Tatsächlich bezieht es sich aber auf das "if", d.h. bei jedem Wert, der nicht ungleich 1 ist - doppelte Verneinung schafft Unklarheit! Bei jedem Wert der 1 ist! - wird true ausgegeben.
Stünde das "else" genau unter dem "if", dann würde man das sofort sehen.


rlk
Senior
Dabei seit: 16.03.2007
Mitteilungen: 10975
Herkunft: Wien
Beitrag No.29, eingetragen 2020-11-24 18:17

Hallo Kajam,
hier noch einmal Dein Programm aus Beitrag 23 mit korrigierter Einrückung der Zeilen 22-25. Wie Du in Beitrag 25) richtig schreibst, wird in der zweiten Schleife für i == 1 die Bedingung count[i] != 1 nicht erfüllt, es wird daher der else-Zweig der if-Anweisung ausgeführt und daher "true" ausgegeben.
Danach wird Zeile 25 ausgeführt, was passiert dort?
C++
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. bool justOnce(int *feld, int size);
  6.  
  7. bool justOnce(int feld[], int size)
  8. {
  9. if (size==-1) {feld[0] = -7; return false;}
  10. if (feld == NULL)
  11. throw runtime_error("nullptr not expected");
  12. int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  13. for (int i = 0; i < size; i++) {
  14. if (feld[i] <= 9 && feld[i] >= 1)
  15. count[feld[i]]++;
  16. }
  17. for (int i = 1; i < 10; i++) {
  18. if (count[i] != 1){
  19. cout << "false" << endl;
  20. return false;
  21. }
  22. else {
  23. cout << "true" << endl;
  24. }
  25. return true;
  26. };
  27. }
  28. int main() {
  29. int feld[9] = {1, 2, 3, 9, 5, 6, 7, 8, 9,};
  30. justOnce(feld, 9);
  31. return 0;
  32. }

Du scheinst nicht klar zwischen der Ausgabe (mit cout << wert) und der Rückgabe eines Funktionswerts (mit return wert zu unterscheiden.

Du solltest den von justOnce gelieferten Wert im Hauptprogramm main prüfen und dort eine geeigneten Text ausgeben. Zur Fehlersuche ist aber die Ausgabe von Zwischenergebnissen im der Funktion justOnce hilfreich.

Servus,
Roland

[Die Antwort wurde nach Beitrag No.27 begonnen.]


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.30, vom Themenstarter, eingetragen 2020-11-24 18:46

2020-11-24 18:07 - piteo in Beitrag No. 28 schreibt:
schon bei i=4 stimmt es nicht: count[4] wird nämlich nicht erhöht, sondern count[5], da feld[4] ja den Wert 5 hat. count sieht danach also so aus:
{0,1,1,1,0,1,0,0,0,1}

Die Aufgabenstellung lautet: justOnce gibt true zurück, wenn ...
und nicht: justOnce gibt "true" aus, wenn ...
Aus der Funktion müssen also alle cout-Ausgaben raus.

Wenn Du true ausgeben willst, wenn ..., dann musst Du im main-Programm den Rückgabewert der Funktion justOnce ausgeben, z.B. so:

cout << justOnce(feld, 9) << endl

Es wäre doch schade, wenn die Freude am Programmieren sich nicht irgendwann einstellt.

Und was der Ein... mit Formatierung meint:
das "else", hinter dem "true" ausgegeben wird, steht unter "for", deshalb meint man, es kommt erst nach der for-Schleife.
Tatsächlich bezieht es sich aber auf das "if", d.h. bei jedem Wert, der nicht ungleich 1 ist - doppelte Verneinung schafft Unklarheit! Bei jedem Wert der 1 ist! - wird true ausgegeben.
Stünde das "else" genau unter dem "if", dann würde man das sofort sehen.


Bei i=4 muss count[5] erhöht werden, stimmt. Dann sieht das ganze am Ende wie folgt aus: {0,1,1,1,0,1,1,1,1,2}

Wo und was ist also jetzt der Fehler? Das "nicht ungleich" 1 bedeutet also genau 1. Aber es wird mir immer noch die ganze Zeit "true" zurück gegeben, wiewohl die Zahl "9" zwei mal vorkommt. Ich evrstehe immer nich nicht ganz?

#include <iostream>
 
using namespace std;
 
bool justOnce(int *feld, int size);
 
bool justOnce(int feld[], int size)
{
    if (size==-1) {feld[0] = -7; return false;}
    if (feld == NULL)
        throw runtime_error("nullptr not expected");
    int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    for (int i = 0; i < size; i++) {
        if (feld[i] <= 9 && feld[i] >= 1)
            count[feld[i]]++;
    }
    for (int i = 1; i < 10; i++) {
        if (count[i] != 1) {
        cout << "false" << endl;
        return false;
 
        }
            else {
            cout << "true" << endl;
            return true;
        }
 
    }};
 
    int main() {
    int feld[9] = {1, 2, 3, 9, 5, 6, 7, 8, 9};
    justOnce(feld, 9);
    cout << justOnce(feld, 9) << endl;
    return 0;
 
}
 
 
 
 


[Die Antwort wurde nach Beitrag No.28 begonnen.]


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.31, vom Themenstarter, eingetragen 2020-11-24 19:10

2020-11-24 18:17 - rlk in Beitrag No. 29 schreibt:
Hallo Kajam,
hier noch einmal Dein Programm aus Beitrag 23 mit korrigierter Einrückung der Zeilen 22-25. Wie Du in Beitrag 25) richtig schreibst, wird in der zweiten Schleife für i == 1 die Bedingung count[i] != 1 nicht erfüllt, es wird daher der else-Zweig der if-Anweisung ausgeführt und daher "true" ausgegeben.
Danach wird Zeile 25 ausgeführt, was passiert dort?
C++
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. bool justOnce(int *feld, int size);
  6.  
  7. bool justOnce(int feld[], int size)
  8. {
  9. if (size==-1) {feld[0] = -7; return false;}
  10. if (feld == NULL)
  11. throw runtime_error("nullptr not expected");
  12. int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  13. for (int i = 0; i < size; i++) {
  14. if (feld[i] <= 9 && feld[i] >= 1)
  15. count[feld[i]]++;
  16. }
  17. for (int i = 1; i < 10; i++) {
  18. if (count[i] != 1){
  19. cout << "false" << endl;
  20. return false;
  21. }
  22. else {
  23. cout << "true" << endl;
  24. }
  25. return true;
  26. };
  27. }
  28. int main() {
  29. int feld[9] = {1, 2, 3, 9, 5, 6, 7, 8, 9,};
  30. justOnce(feld, 9);
  31. return 0;
  32. }

Du scheinst nicht klar zwischen der Ausgabe (mit cout << wert) und der Rückgabe eines Funktionswerts (mit return wert zu unterscheiden.

Du solltest den von justOnce gelieferten Wert im Hauptprogramm main prüfen und dort eine geeigneten Text ausgeben. Zur Fehlersuche ist aber die Ausgabe von Zwischenergebnissen im der Funktion justOnce hilfreich.

Servus,
Roland

[Die Antwort wurde nach Beitrag No.27 begonnen.]

In Zeile 25 wird dann "true" ausgegeben. Und das Programm beendet sich dann? Das heißt, es wird nur der erste Wert überprüft und die Schleife ist sinnlos? Wie mache ich denn das so, dass alle Indizies "i" überprüft werden, und nur "true" ausgegeben wird, wenn alle count[i]´s gleich 1 sind? Geht das überhaupt mit dieser Methode der Ausgabe von "cout" als Zwischenergebnissen in der Funktion "JustOnce"?

Ich denke nach und nach aber irgendwie sehe ich das nicht gelöst..

Ich liebe C++.


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.32, eingetragen 2020-11-24 20:10

2020-11-24 19:10 - Kajam in Beitrag No. 31 schreibt:

In Zeile 25 wird dann "true" ausgegeben. Und das Programm beendet sich dann? Das heißt, es wird nur der erste Wert überprüft und die Schleife ist sinnlos? Wie mache ich denn das so, dass alle Indizies "i" überprüft werden, und nur "true" ausgegeben wird, wenn alle count[i]´s gleich 1 sind?

Indem man (wie in der Musterlösung) NACH der Schleife true zurückgibt und gegebenenfalls vor Rückgabe ausgibt.
Du gibst es WÄHREND der Schleife bereits zurück und beendest damit Funktion und Schleife, bevor alle Ziffern überprüft sind.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.33, vom Themenstarter, eingetragen 2020-11-24 20:32

2020-11-24 20:10 - DerEinfaeltige in Beitrag No. 32 schreibt:
2020-11-24 19:10 - Kajam in Beitrag No. 31 schreibt:

In Zeile 25 wird dann "true" ausgegeben. Und das Programm beendet sich dann? Das heißt, es wird nur der erste Wert überprüft und die Schleife ist sinnlos? Wie mache ich denn das so, dass alle Indizies "i" überprüft werden, und nur "true" ausgegeben wird, wenn alle count[i]´s gleich 1 sind?

Indem man (wie in der Musterlösung) NACH der Schleife true zurückgibt und gegebenenfalls vor Rückgabe ausgibt.
Du gibst es WÄHREND der Schleife bereits zurück und beendest damit Funktion und Schleife, bevor alle Ziffern überprüft sind.

Das kriege ich irgendwie nicht anders hin. Das Programm will die geschweifte Klammer vor "else" stehen haben... :(

Und: Ist es eigentlich nicht so, dass wenn das Programm die "else"- Schleife erreicht, dann auch einfach "true" ausgibt und sich dann beendet? Wenn nicht, wieso? WAS ist der Unterschied zu dem mit "WÄHREND der Schleife" ?




piteo
Aktiv
Dabei seit: 12.09.2014
Mitteilungen: 25
Beitrag No.34, eingetragen 2020-11-25 00:37

Das Programm will die geschweifte Klammer vor else haben, richtig, weil das, was hinter if (...) kommt, entweder eine Anweisung ist, oder eine Menge von Anweisungen zwischen geschweiften Klammern.
Genau so verhält es sich auch bei der for-Schleife: Nach for (...) kommt eine öffnende geschweifte Klammer, die zugehörige schließende ist die zweite vor else. So gehört "else" also zu "for" statt zu "if", und das mag das Programm nicht.

Noch etwas:
else-Schleifen gibt es nicht. Hinter "else" kommt das, was Dein Programm machen soll, wenn die Bedingung in den Klammern hinter "if" nicht erfüllt ist. Und das ist nicht: dem "rufenden" main-Programm zu sagen: "true", alles stimmt. Das wäre zu früh, wenn die for-Schleife noch gar nicht dazu gekommen ist, i auf 2 zu erhöhen (das macht das i++), damit das dritte Element von count angesehen wird (das mit dem Index 2).

Die Idee der zweiten Schleife ist: Wenn eine Ziffer nicht genau einmal vorkommt, dann kann dem main-Programm sofort mitgeteilt werden: false! Ansonsten müssen aber alle 9 Ziffern geprüft werden, um zu wissen: "Jede Ziffer kommt genau einmal vor". Erst nach Abschluss der Schleife, wenn nämlich i nicht mehr kleiner als 10 ist, kann dem main-Programm mitgeteilt werden: true!


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.35, eingetragen 2020-11-25 08:51

Noch ein Tipp bevor du weitermachst:

Informiere dich, wie man in deiner IDE Code automatisch formattiert.
Vermutlich reicht es, den Code via Strg+A zu markieren und per Rechtsklick im Kontextmenü "Format ..." oder ähnliches auszuwählen.
Wenn nicht, helfen Google und die Dokumentation der verwendeten IDE.

Die falschen Einrückungen machen den Code wahnsinnig schwer zu lesen, da man so Klammern zählen muss, statt auf einen Blick zu erkennen, zu welchem Block welche Anweisung gehört.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.36, vom Themenstarter, eingetragen 2020-11-25 16:30

2020-11-25 00:37 - piteo in Beitrag No. 34 schreibt:
Das Programm will die geschweifte Klammer vor else haben, richtig, weil das, was hinter if (...) kommt, entweder eine Anweisung ist, oder eine Menge von Anweisungen zwischen geschweiften Klammern.
Genau so verhält es sich auch bei der for-Schleife: Nach for (...) kommt eine öffnende geschweifte Klammer, die zugehörige schließende ist die zweite vor else. So gehört "else" also zu "for" statt zu "if", und das mag das Programm nicht.

Noch etwas:
else-Schleifen gibt es nicht. Hinter "else" kommt das, was Dein Programm machen soll, wenn die Bedingung in den Klammern hinter "if" nicht erfüllt ist. Und das ist nicht: dem "rufenden" main-Programm zu sagen: "true", alles stimmt. Das wäre zu früh, wenn die for-Schleife noch gar nicht dazu gekommen ist, i auf 2 zu erhöhen (das macht das i++), damit das dritte Element von count angesehen wird (das mit dem Index 2).

Die Idee der zweiten Schleife ist: Wenn eine Ziffer nicht genau einmal vorkommt, dann kann dem main-Programm sofort mitgeteilt werden: false! Ansonsten müssen aber alle 9 Ziffern geprüft werden, um zu wissen: "Jede Ziffer kommt genau einmal vor". Erst nach Abschluss der Schleife, wenn nämlich i nicht mehr kleiner als 10 ist, kann dem main-Programm mitgeteilt werden: true!

Ich habe den Kommentar, das "return true;" hinter die for-Schleife einzufügen, beherzigt. Nun funktioniert das einigermaßen. Was mir aber auffällt: Es werden sehr viele true´s zurückgegeben. Ich frage mich, woran das jetzt liegt? Müssen nicht nur lediglich "9" Stück (true´s) zurückgegeben werden, da "Feld[9]"ist?:
C++
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. bool justOnce(int *feld, int size);
  6.  
  7. bool justOnce(int feld[], int size)
  8. {
  9. if (size==-1)
  10. {
  11. feld[0] = -7;
  12. return false;
  13. }
  14. if (feld == NULL)
  15. throw runtime_error("nullptr not expected");
  16. int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  17. for (int i = 0; i < size; i++)
  18. {
  19. if (feld[i] <= 9 && feld[i] >= 1)
  20. count[feld[i]]++;
  21. }
  22.  
  23. for (int i = 1; i < 10; i++)
  24. {
  25. if (count[i] != 1)
  26. {
  27. cout << "false" << endl;
  28. return false;
  29.  
  30.  
  31. }
  32. else
  33. {
  34. cout << "true" << endl;
  35.  
  36. }
  37. }
  38. return true;
  39. };
  40.  
  41. int main()
  42. {
  43. int feld[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
  44. justOnce(feld, 9);
  45. cout << justOnce(feld, 9) << endl;
  46. return 0;
  47.  
  48. }



Bei "false" werden mir 8 false´s ausgegeben. Ich habe ja  {1, 2, 3, 9, 5, 6, 7, 8, 9};

1: true
2: true
3: true
4: false
5: true
6: true
7: true
8: true
9: false

oder nicht? Es wird ausgegeben:



Hier ist 8 "false". Irgendwas stimmt nicht oder? Ist das normal?


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.37, vom Themenstarter, eingetragen 2020-11-25 16:44

2020-11-25 16:30 - Kajam in Beitrag No. 36 schreibt:
2020-11-25 00:37 - piteo in Beitrag No. 34 schreibt:
Das Programm will die geschweifte Klammer vor else haben, richtig, weil das, was hinter if (...) kommt, entweder eine Anweisung ist, oder eine Menge von Anweisungen zwischen geschweiften Klammern.
Genau so verhält es sich auch bei der for-Schleife: Nach for (...) kommt eine öffnende geschweifte Klammer, die zugehörige schließende ist die zweite vor else. So gehört "else" also zu "for" statt zu "if", und das mag das Programm nicht.

Noch etwas:
else-Schleifen gibt es nicht. Hinter "else" kommt das, was Dein Programm machen soll, wenn die Bedingung in den Klammern hinter "if" nicht erfüllt ist. Und das ist nicht: dem "rufenden" main-Programm zu sagen: "true", alles stimmt. Das wäre zu früh, wenn die for-Schleife noch gar nicht dazu gekommen ist, i auf 2 zu erhöhen (das macht das i++), damit das dritte Element von count angesehen wird (das mit dem Index 2).

Die Idee der zweiten Schleife ist: Wenn eine Ziffer nicht genau einmal vorkommt, dann kann dem main-Programm sofort mitgeteilt werden: false! Ansonsten müssen aber alle 9 Ziffern geprüft werden, um zu wissen: "Jede Ziffer kommt genau einmal vor". Erst nach Abschluss der Schleife, wenn nämlich i nicht mehr kleiner als 10 ist, kann dem main-Programm mitgeteilt werden: true!

Ich habe den Kommentar, das "return true;" hinter die for-Schleife einzufügen, beherzigt. Nun funktioniert das einigermaßen. Was mir aber auffällt: Es werden sehr viele true´s zurückgegeben. Ich frage mich, woran das jetzt liegt? Müssen nicht nur lediglich "9" Stück (true´s) zurückgegeben werden, da "Feld[9]"ist?:

#include <iostream>
 
using namespace std;
 
bool justOnce(int *feld, int size);
 
bool justOnce(int feld[], int size)
{
    if (size==-1)
    {
        feld[0] = -7;
        return false;
    }
    if (feld == NULL)
        throw runtime_error("nullptr not expected");
    int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    for (int i = 0; i < size; i++)
    {
        if (feld[i] <= 9 && feld[i] >= 1)
            count[feld[i]]++;
    }
 
    for (int i = 1; i < 10; i++)
    {
        if (count[i] != 1)
        {
            cout << "false" << endl;
            return false;
 
 
        }
        else
        {
            cout << "true" << endl;
 
        }
    }
    return true;
};
 
int main()
{
    int feld[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    justOnce(feld, 9);
    cout << justOnce(feld, 9) << endl;
    return 0;
 
}
 
 
 
 



Bei "false" werden mir 8 false´s ausgegeben. Aber: Ich habe ja  {1, 2, 3, 9, 5, 6, 7, 8, 9}; - das sind 9 Felder.

1: true
2: true
3: true
4: false
5: true
6: true
7: true
8: true
9: false

oder nicht? Es wird ausgegeben:



Hier ist das Feld[8] "false". Irgendwas stimmt nicht oder? Ist das normal?



Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.38, vom Themenstarter, eingetragen 2020-11-25 16:46

2020-11-25 08:51 - DerEinfaeltige in Beitrag No. 35 schreibt:
Noch ein Tipp bevor du weitermachst:

Informiere dich, wie man in deiner IDE Code automatisch formattiert.
Vermutlich reicht es, den Code via Strg+A zu markieren und per Rechtsklick im Kontextmenü "Format ..." oder ähnliches auszuwählen.
Wenn nicht, helfen Google und die Dokumentation der verwendeten IDE.

Die falschen Einrückungen machen den Code wahnsinnig schwer zu lesen, da man so Klammern zählen muss, statt auf einen Blick zu erkennen, zu welchem Block welche Anweisung gehört.

Danke für den Tipp. Die Formatierung funktioniert.


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.39, eingetragen 2020-11-25 17:18

Du rufst die Funktion in der main zweimal auf.

Im ersten Fall erhälst du daher in der zweiten Schleife 9 mal die Ausgabe des Strings "true", insgesamt also 18 mal.
Weiterhin gibst du das Ergebnis des Funktionsaufrufs an die Konsole aus.
Dieses ist "1", da der bool'sche Wert true als Zahl 1 interpretiert wird.


Im zweiten Fall gibst du erst für 1,2,3 jeweils den String "true" an die Konsole aus.
Bei 4 wird dann die if-Bedingung erfüllt, der String "false" ausgegeben und der Wert false zurückgegeben.
Es wird also zweimal "true", "true", "true", "false" und anschließend der Rückgabewert false als 0 ausgegeben.


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.40, eingetragen 2020-11-25 17:20

Welchen Sinn hat Beitrag #37?
Soweit ich erkennen kann ist es nur ein Quote von #36 🤔

In #36 habe ich die Code-Darstellung vervollständigt.
Zum einen solltest du bei längeren Codes diesen mit Numerierung ausgeben, also auf das [num] von [Quelltext [num.] klicken.
Und wenn du es dann noch schaffst, bei dem eingefügten Text

\­sourceon nameDerSprache
\numberson

\sourceoff

das nameDerSprache durch C++ zu ersetzen, dann ist ein weiterer Schritt für die Lesbarkeit getan.

[Die Antwort wurde nach Beitrag No.38 begonnen.]


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.41, vom Themenstarter, eingetragen 2020-11-25 17:23

2020-11-25 16:44 - Kajam in Beitrag No. 37 schreibt:
2020-11-25 16:30 - Kajam in Beitrag No. 36 schreibt:
2020-11-25 00:37 - piteo in Beitrag No. 34 schreibt:
Das Programm will die geschweifte Klammer vor else haben, richtig, weil das, was hinter if (...) kommt, entweder eine Anweisung ist, oder eine Menge von Anweisungen zwischen geschweiften Klammern.
Genau so verhält es sich auch bei der for-Schleife: Nach for (...) kommt eine öffnende geschweifte Klammer, die zugehörige schließende ist die zweite vor else. So gehört "else" also zu "for" statt zu "if", und das mag das Programm nicht.

Noch etwas:
else-Schleifen gibt es nicht. Hinter "else" kommt das, was Dein Programm machen soll, wenn die Bedingung in den Klammern hinter "if" nicht erfüllt ist. Und das ist nicht: dem "rufenden" main-Programm zu sagen: "true", alles stimmt. Das wäre zu früh, wenn die for-Schleife noch gar nicht dazu gekommen ist, i auf 2 zu erhöhen (das macht das i++), damit das dritte Element von count angesehen wird (das mit dem Index 2).

Die Idee der zweiten Schleife ist: Wenn eine Ziffer nicht genau einmal vorkommt, dann kann dem main-Programm sofort mitgeteilt werden: false! Ansonsten müssen aber alle 9 Ziffern geprüft werden, um zu wissen: "Jede Ziffer kommt genau einmal vor". Erst nach Abschluss der Schleife, wenn nämlich i nicht mehr kleiner als 10 ist, kann dem main-Programm mitgeteilt werden: true!

Ich habe den Kommentar, das "return true;" hinter die for-Schleife einzufügen, beherzigt. Nun funktioniert das einigermaßen. Was mir aber auffällt: Es werden sehr viele true´s zurückgegeben. Ich frage mich, woran das jetzt liegt? Müssen nicht nur lediglich "9" Stück (true´s) zurückgegeben werden, da "Feld[9]"ist?:

#include <iostream>
 
using namespace std;
 
bool justOnce(int *feld, int size);
 
bool justOnce(int feld[], int size)
{
    if (size==-1)
    {
        feld[0] = -7;
        return false;
    }
    if (feld == NULL)
        throw runtime_error("nullptr not expected");
    int count[10] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    for (int i = 0; i < size; i++)
    {
        if (feld[i] <= 9 && feld[i] >= 1)
            count[feld[i]]++;
    }
 
    for (int i = 1; i < 10; i++)
    {
        if (count[i] != 1)
        {
            cout << "false" << endl;
            return false;
 
 
        }
        else
        {
            cout << "true" << endl;
 
        }
    }
    return true;
};
 
int main()
{
    int feld[9] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    justOnce(feld, 9);
    cout << justOnce(feld, 9) << endl;
    return 0;
 
}
 
 
 
 



Bei "false" werden mir 8 false´s ausgegeben. Aber: Ich habe ja  {1, 2, 3, 9, 5, 6, 7, 8, 9}; - das sind 9 Felder.

1: true
2: true
3: true
4: false
5: true
6: true
7: true
8: true
9: false

oder nicht? Es wird ausgegeben:



Hier ist das Feld[8] "false". Irgendwas stimmt nicht oder? Ist das normal?



Und wieso macht das Programm hier mit der zweiten for-Schleife weiter, nachdem "return false;" ausgeführt worden ist? Wieso funktioniert das hier? Ich blicke hier nicht durch ... ;(

[Die Antwort wurde nach Beitrag No.38 begonnen.]


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.42, eingetragen 2020-11-25 17:24

Du kannst uns erzählen, was du willst😲
Bei dieses Fragen hast du nie und nimmer einen Bleistifttest (auch Schreibtischtest genannt) durchgeführt. Oder zumindest nicht ordentlich.
Denn dann würde dir sofort auffallen, woher die ganzen trues und falses kommen.

[Die Antwort wurde nach Beitrag No.40 begonnen.]


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.43, eingetragen 2020-11-25 17:25

Und das Ganze noch einmal zu quoten bringt auch keine neuen Erkenntnisse.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.44, vom Themenstarter, eingetragen 2020-11-25 17:41

2020-11-25 17:18 - DerEinfaeltige in Beitrag No. 39 schreibt:
Du rufst die Funktion in der main zweimal auf.

Im ersten Fall erhälst du daher in der zweiten Schleife 9 mal die Ausgabe des Strings "true", insgesamt also 18 mal.
Weiterhin gibst du das Ergebnis des Funktionsaufrufs an die Konsole aus.
Dieses ist "1", da der bool'sche Wert true als Zahl 1 interpretiert wird.


Im zweiten Fall gibst du erst für 1,2,3 jeweils den String "true" an die Konsole aus.
Bei 4 wird dann die if-Bedingung erfüllt, der String "false" ausgegeben und der Wert false zurückgegeben.
Es wird also zweimal "true", "true", "true", "false" und anschließend der Rückgabewert false als 0 ausgegeben.

Das ganze verdoppelt sich also. Und nach false wird auch das Programm beendet.

Was ist denn die Aufrufung der Funktion in der main?
Das hier: justOnce(feld, 9); ?
Wo ist denn die zweite Aufrung?
Könntest du mir das erklären, weil das ist mir neu.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.45, vom Themenstarter, eingetragen 2020-11-25 17:43

2020-11-25 17:24 - viertel in Beitrag No. 42 schreibt:
Du kannst uns erzählen, was du willst😲
Bei dieses Fragen hast du nie und nimmer einen Bleistifttest (auch Schreibtischtest genannt) durchgeführt. Oder zumindest nicht ordentlich.
Denn dann würde dir sofort auffallen, woher die ganzen trues und falses kommen.

[Die Antwort wurde nach Beitrag No.40 begonnen.]

In Beitrag #25 habe ich den Bleistifttest gemacht.

Und ich werde mich für die Lesebarkeit bemühen.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.46, vom Themenstarter, eingetragen 2020-11-25 17:59

Das Problem ist jetzt: Ich möchte, dass mir alle true´s und false´s via "cout" ausgegeben werden. Das geht aber doch gar nicht, wenn return false; und return true; im Programm integriert sind, denn das Programm schließt sich immer, sobald eins davon erfüllt ist. Das heißt, ich lösche die Ausgaben via "cout" und lasse es einfach mit cout << justOnce(feld, 9) ausgeben. Ich bekomme nicht einzelne Ausgaben der Felder, ob true oder false, sondern das Endresultat, ob ture(1) oder false(0).

Liege ich hier richtig?


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.47, eingetragen 2020-11-25 18:31

2020-11-25 17:59 - Kajam in Beitrag No. 46 schreibt:
Das Problem ist jetzt: Ich möchte, dass mir alle true´s und false´s via "cout" ausgegeben werden.

Warum willst du das?

Die Aufgabe ist, eine Funktion zu implementieren, die überprüft, ob das Array die gewünschte Eigenschaft besitzt, jede Zahl von 1 bis 9 exakt einmal zu enthalten.
Die Antwort ist als bool'scher Wert zurückzugeben.

Eine Ausgabe ist allenfalls zu Test- oder Demonstrationszwecken interessant, hat aber weder mit der Funktionalität noch der Aufgabenstellung etwas zu tun.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.48, vom Themenstarter, eingetragen 2020-11-25 19:44

Aber wieso wird alles zwei mal ausgegeben. Was ist jetzt doppelt? Ich habe das hier so gemacht wie die Programme davor...


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.49, eingetragen 2020-11-25 20:09

Was genau passiert denn in deiner main-Funktion?


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.50, vom Themenstarter, eingetragen 2020-11-25 20:14

1. Es wird ein Array definiert.
2. Die Funktion boolOnce(feld, 9) über der Main Funktion wird ausgeführt.
3. Es wird die Funktion ausgegeben. 1 oder 0.


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.51, eingetragen 2020-11-25 20:22

Und genau das soll doch passieren.
Vorausgesetzt, daß onlyOnce (nicht boolOnce😉) das Ergebnis korrekt ermittelt und zurückgibt.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.52, vom Themenstarter, eingetragen 2020-11-25 21:49

Und hier wird nur einmalig 1 oder 0 zurück gegeben, nicht doppelt. Aber davor alles doppelt (mehrmals) mit den ganzen trues und falses. Woran lag das? Ich will das noch verstehen :)


DerEinfaeltige
Senior
Dabei seit: 11.02.2015
Mitteilungen: 2709
Beitrag No.53, eingetragen 2020-11-25 22:42
C++
    justOnce(feld, 9);
 

Hier rufst du die Funktion auf.
Als Seiteneffekt werden ein paar Ausgaben an die Standardausgabe geleitet.
Der Rückgabewert der Funktion wird ignoriert.


C++
    cout << justOnce(feld, 9) << endl;
 

Hier rufst du die Funktion erneut mit den gleichen Argumenten auf und leitest den Rückgabewert diesmal an die Standardausgabe.
Wieder treten als Seiteneffekt ein paar Ausgaben an die Standardausgabe auf.


Kajam
Aktiv
Dabei seit: 18.02.2020
Mitteilungen: 316
Beitrag No.54, vom Themenstarter, eingetragen 2020-11-25 23:35

Aso, beides (justOnce(feld, 9);, und cout << justOnce(feld, 9) << endl;)
ist eine Funktionsaufrufung und quasi das gleiche? Das heißt, ich kann eins davon wegnehmen? Dann am besten das erste, denn das zweite ignoriert den Ruckgabewert 0 oder 1 also nicht. Alles klar.


viertel
Senior
Dabei seit: 04.03.2003
Mitteilungen: 27765
Herkunft: Hessen
Beitrag No.55, eingetragen 2020-11-26 01:38

Und immer noch behaupte ich:
Bei einem ordentlichen Schreibtischtest hättest du selbst gemerkt, woher die doppelte Ausgabe kommt!
Aber es ist ja so viel einfacher, sich hier die Finger wund zu schreiben und zu fragen, solange noch jemand Lust hat, zu antworten.

In einer Klausur hast du dann niemanden, den du fragen kannst.
Wenn du dann die Techniken nicht kennst/kannst, läufst du gegen die Wand😛




Dieses Forumbeitrag kommt von Matroids Matheplanet
https://https://matheplanet.de

Die URL für dieses Forum-Thema ist:
https://https://matheplanet.de/default3.html?topic=250552=5101
Druckdatum: 2021-03-05 09:08