[java] lussen

Moderators: jkien, Xilvo

Gebruikersavatar
Berichten: 2.902

[java] lussen

Ik een probleem om de oplossing van de volgende opgave te begrijpen:

Lees een getal karaktergewijs. Met de methode readChar() dient karakter per karakter gelezen te worden in een herhalingslus. Bouw uitgaande van de karaktertekens de gehele waarde op. Schrijf deze waarde tenslotte als integer op het scherm.

Voorbeeld: de karaktertekens '1''2''3' worden afzonderlijk ingelezen en het gehele getal 123 wordt daaruit gevormd en getoond op het scherm.

Oplossing:

Code: Selecteer alles

public class Oef3_4

{

public static void main (String [] args)

{

Input inp = new Input();

System.out.print("Invoer: ");

char ch; int getal=0;

/*

 *ch = inp.readchar();

 *while(ch != '\n')

 *{

 		getal= getal*10+ (int) ch - 48;

 		ch=inp.readChar();

  }

  */

  while((ch=inp.readChar()) != '\n')

   	getal = getal*10 + (int) ch -48;

  

  System.out.println("Getal: "+getal);

  

}

}
Mijn probleem:

1. Ik denk dat je 'int getal' moet ingeven zodat je de karakters kan gaan omzetten naar een geheel getal.

2. Ik snap niet direct waarom men dat gelijk gaat stellen aan 0 ? (het eerste cijfer ('0') heeft ASCII waarde 48 waarom dan niet meteen vertrekken van 48 ?).

Tenslotte snap ik deze regel niet:

Code: Selecteer alles

getal = getal*10 + (int) ch -48;
Kan er mij iemand wat helpen bij mijn bovenstaande vragen ?

Gebruikersavatar
Lorentziaan
Berichten: 99

Re: [java] lussen

1. in "getal" ga je het getal opslaan als int, dus dat moet inderdaad int zijn

2. gelijkstellen aan 0 is hier initialisatie; variabelen moet je altijd netjes initialiseren;

dit is een int, dus we doen hier niets met ASCII waardes, we willen hier het "echte" getal instoppen

3. (int) ch ==> converteer ch naar een int ('0' krijgt nu de waarde 48, '1' krijgt de waarde 49, etc)

(int) ch - 48 ==> trek er 48 vanaf ('0' wordt 0, '1' wordt 1, etc)

getal = getal * 10 + (int) ch - 48 ==> vermenigvuldig met 10 en tel het laatste cijfer erbij.

Probeer nu voor jezelf na te gaan, wat er met de variabele getal gebeurt, als iemand bijvoorbeeld '12' invoert.
Raga

Berichten: 7.068

Re: [java] lussen

1. Ik denk dat je 'int getal' moet ingeven zodat je de karakters kan gaan omzetten naar een geheel getal.
'int getal' een een declaratie van de variabele 'getal' van het type 'int'. Hoe denk je dat dit nodig is voor het omzetten naar een geheel getal?
2. Ik snap niet direct waarom men dat gelijk gaat stellen aan 0 ?
Hoeveel is x+10 als ik je niet vertel hoeveel x nu is?
Tenslotte snap ik deze regel niet:

Code: Selecteer alles

getal = getal*10 + (int) ch -48;
Helpt het als je deze regel alsvolgt opschrijft:

Code: Selecteer alles

getal = 10*getal;

int c = (int) ch;

int d = c - 48; 

getal = getal + d;

Gebruikersavatar
Berichten: 2.902

Re: [java] lussen

Raga schreef:1. in "getal" ga je het getal opslaan als int, dus dat moet inderdaad int zijn

2. gelijkstellen aan 0 is hier initialisatie; variabelen moet je altijd netjes initialiseren;

dit is een int, dus we doen hier niets met ASCII waardes, we willen hier het "echte" getal instoppen

3. (int) ch ==> converteer ch naar een int ('0' krijgt nu de waarde 48, '1' krijgt de waarde 49, etc)

(int) ch - 48 ==> trek er 48 vanaf ('0' wordt 0, '1' wordt 1, etc)

getal = getal * 10 + (int) ch - 48 ==> vermenigvuldig met 10 en tel het laatste cijfer erbij.

Probeer nu voor jezelf na te gaan, wat er met de variabele getal gebeurt, als iemand bijvoorbeeld '12' invoert.
Bedankt voor de snelle en duidelijke uitleg Raga, ik probeer even die 12 te beredeneren ...

Als je nu bijvoorbeeld die 12 gaat invoeren, ik druk dus '12' ENTER, dan denk ik dat er het volgende gaat gebeuren:

het karakter 1 naar het type int gaat 49 worden;

getal = getal*10 + (int) ch -48

0=0*10+49-48

getal=1

de tweede keer dat de lus doorlopen gaat worden dan krijg je dus:

het karakter 2 naar het type int gaat 50 worden;

getal = getal*10 + (int) ch -48

getal=1*10+50-48

getal=12

EDIT: reactie op de post van EvilBro ondertussen
'int getal' een een declaratie van de variabele 'getal' van het type 'int'. Hoe denk je dat dit nodig is voor het omzetten naar een geheel getal?
Ik had mij verkeerd uitgedrukt, ik bedoel eigenlijk dat 'int getal' nodig is om tijdens de berekening het geheeld getal op te slaan. Ik bedoelde het goed maar nu ik de verdere werking van het programma denk te begrijpen zie ik pas dat de bovenstaande verklaring niet echt correct uitgedrukt was.
Hoeveel is x+10 als ik je niet vertel hoeveel x nu is?
Ik wist dat je 'getal' een waarde moet geven maar ik kon niet echt vatten waarom het 0 moest zijn, door de bijdrage van Raga en jou snap ik dat nu.
EvilBro schreef:Helpt het als je deze regel alsvolgt opschrijft:

Code: Selecteer alles

getal = 10*getal;

int c = (int) ch;

int d = c - 48; 

getal = getal + d;
Dat helpt, ik had op die manier mijn eerst antwoord gepost (dat ik nu aan het aanpassen ben).

Nog eens bedankt voor de snelle hulp mensen !!

Gebruikersavatar
Lorentziaan
Berichten: 99

Re: [java] lussen

graag gedaan ruben :D
Raga


Gebruikersavatar
Berichten: 2.902

Re: [java] lussen

Inderdaad Cycloon :D

Ik denk dat ik binnenkort nog wel een aantal keren zal langskomen met een Java probleem, we zijn vollop oefening aan het maken op lussen. Sommige gaan zeer vlot maar anderen lukken totaal niet, met die laatste zal je mij hier wel zien verschijnen :D

Gebruikersavatar
Berichten: 2.902

Re: [java] lussen

Ik heb opnieuw een probleem:

De vraag is als volgt:

Bepaal alle perfecte getallen kleiner dan een in te lezen grenswaarde. Voor een perfect getal gedt dat de som van de delers gelijk is aan het getal zelf. Voorbeeld van een perfect getal is 6, de delers zijn namelijk 1,2,3 met als som 6.

Code: Selecteer alles

public class Oef3_6

{

public static void main (String [] args)

{

Input l = new Input();

System.out.print("Voer grenswaarde in: ");

int grens = l.readInt();

int getal=1;

while(getal<=grens)

{

 ...

}

}
Eerst ga ik dus de grenswaarde inlezen, vervolgens zou ik een lus willen maken die blijft lopen zolang het getal dat begint bij 1 kleiner of gelijk is aan de grenswaarde.

Hoe ik juist verder moet doen zie ik niet, het getal dat hij gaat genereren: 1,2,3, ... zou denk ik moeten worden opgeslagen in een apparte geheugenplaats en daarna de som nemen van een aantal getalen en controleren of het deelbaar is. Ik vrees dat dit te moeilijk is en dat er een betere manier moet bestaan voor dit probleem


Gebruikersavatar
Berichten: 4.810

Re: [java] lussen

Code: Selecteer alles

public class Oef3_6

{

	public static void main (String [] args)

	{

		Input l = new Input();

		System.out.print("Voer grenswaarde in: ");

		int grens = l.readInt();

		for (int i=1;i<grens;i++) {

			int som=0,j=1;

			while(j<=i/2 && som<i) {

				if(i%j==0) som+=j;

				j++;

			}

			if(som==i) System.out.println(i+" ");

		}

	}

}


Je gaat dus idd een lusje maken die alle getallen bepaalt kleiner dan de ingegeven waarde, en van die getallen ga je telkes de delers bepalen (er zijn hoogstens delers tot de halve waarde van het getal). Je telt al deze delers op, en indien de som == het getal dan is het een perfect getal.

Gebruikersavatar
Berichten: 4.810

Re: [java] lussen

Er staat in bovenstaande code trouwens nog een klein foutje:

Code: Selecteer alles

som<i
moet worden:

Code: Selecteer alles

som<=i

Gebruikersavatar
Berichten: 2.902

Re: [java] lussen

Bedankt voor de hulp Cycloon !

Mijn idee was om al die delers van die getallen dan weer te geven maar ik denk dat dit niet mogelijk is.

Blijkbaar zijn er ook niet zoveel perfecte getallen, met een grens van 1000 krijg ik er 3 namelijk: 6, 28 en 496.

Berichten: 7.068

Re: [java] lussen

Code: Selecteer alles

public class Onzin

{

	public static void main (String [] args)

	{

		int grens = 100;

		for (int i = 1; i < grens; i++) {

			int[] delers = findProperDivisors(i);

			int som = sumIntArray(delers);

			if (som == i) {

			   System.out.println("perfect getal " + i + " heeft de volgende delers: " + printIntArray(delers));

			}

		}

	}



	public static int[] findProperDivisors(int number) {

		// methode vindt de delers van een getal en zet ze in een array.

	}



	public static int sumIntArray(int[] numbers) {

		// tel alle getallen in het array op.

	}



	public static String printIntArray(int[] numbers) {

		// stop de getallen in het array in een string.

	}

}
Ik zou zeggen: vul de methodes in en je hebt een programma dat doet wat je onmogelijk achtte.

Gebruikersavatar
Berichten: 4.810

Re: [java] lussen

Je kan dat in principe wel doen door te werken met een vector ofzoiets. Maar dat lijkt me idd een beetje onzinnig om hier te doen. Er zijn in totaal 4 perfecte getallen die je zou kunnen vinden (eentje nog ergens in de 4000). Het volgende perfecte getal zit ergens over de paar miljoen (en dit zou immens lang duren om uit te rekenen met die programmatje :D ).

Gebruikersavatar
Berichten: 2.902

Re: [java] lussen

...// Er zijn in totaal 4 perfecte getallen die je zou kunnen vinden (eentje nog ergens in de 4000). ...//
Er is volgens mijn programma geen perfect getal in de 4000, 8128 is er wel eentje.

Ik heb hem eens een miljard laten berekenen als grenswaarde maar blijkbaar duurt dat net iets langer als 10000 :D

Gebruikersavatar
Berichten: 4.810

Re: [java] lussen

Ruben01 schreef:Er is volgens mijn programma geen perfect getal in de 4000, 8128 is er wel eentje.

Ik heb hem eens een miljard laten berekenen als grenswaarde maar blijkbaar duurt dat net iets langer als 10000 :D


Ohja idd, het was 8128. De reden dat een milard berekenen zo lang duurt is omdat je telkes meer en meer getallen moet gaan bekijken of ze wel een deler zijn (bij een 100.000 bv moet je al 50000 keer door de while lus).

Reageer