Permalänk

Hjälp med java.

Hej, sitter och gör lite övningar ifrån boken och en av dom var att skapa ett program som läser av vad användaren skriver in för värden, och sen printar ut cumulative totals. Exempelvis om jag skriver in 1, 7, 2, 9 så ska programmet printa ut 1, 8, 10, 19.

Jag försökte själv först med koden, men kom inte på hur jag skulle göra för att printa ut dom på sättet ovan. Jag sökte då runt lite och hittade flera lösningar som i stort sett vad likadana, där man använde en String för att printa ut totalen på samma sätt som i exemplet. Problemet är bara att jag inte förstår riktigt hur det funkar med stringen. Jag klistrar in koden nedan.

public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Ange ett antal heltal."); String cumulativeTotals = ""; //Skapar stringen cumulativeTotals double sum = 0; //Sätter talsumman till 0 while(in.hasNextDouble()) { double input = in.nextDouble(); //Sätter värdet användaren skriver in till variabeln input sum += input; //Lägger till input till summan(som börjar på 0) cumulativeTotals = cumulativeTotals + " " + sum; // } System.out.println(cumulativeTotals); } }

Vad jag inte förstår är hur Stringen cumulativeTotals printar ut summan av talen efter varandra som i exemplet. Stringen assignas ju till " ", som kan ses som en tom string(eller?).

Tack på förhand.

Permalänk
Medlem

Hej,
cumulativeTotals är en String.
När du adderar strängar så läggs dom ihop efter varandra.
Tex:
"Hej" + "hopp" + " " + "gummisn**p" = "Hejhopp gummisn**p"
Det som sker på denna raden är att strängarna/tecknena läggs till efter varandra istället för att siffrorna adderas så som man normalt gör med tex integer variabler(dvs siffror).

cumulativeTotals = cumulativeTotals + " " + sum; //
Raden ovan sätter strängen cumulativeTotals till likamed följande => "strängen cumulativeTotals" ihoplagd med "strängen mellanslag(" ")" ihoplagd med variabeln sum.
Detta upprepas i en loop och bygger på så sätt på strängen "cumulativeTotals" för varje loop.
Loopen upprepas sålänge detta är sant: while(in.hasNextDouble())
...dvs så länge det finns fler inmatade tal att gå igenom.

Strängen cumulativeTotals printas inte ut förrens programmet når följande rad:
System.out.println(cumulativeTotals);

hmm. Hoppas det hjälper. Är rädd att jag kanske gjorde det rörigare istället.

Permalänk
Skrivet av FANTEN:

Hej,
cumulativeTotals är en String.
När du adderar strängar så läggs dom ihop efter varandra.
Tex:
"Hej" + "hopp" + " " + "gummisn**p" = "Hejhopp gummisn**p"
Det som sker på denna raden är att strängarna/tecknena läggs till efter varandra istället för att siffrorna adderas så som man normalt gör med tex integer variabler(dvs siffror).

cumulativeTotals = cumulativeTotals + " " + sum; //
Raden ovan sätter strängen cumulativeTotals till => strängen cumulativeTotals läggs ihop med strängen mellanslag(" ") och lägger sen till sum.
Detta upprepas i en loop och bygger på så sätt på strängen "cumulativeTotals" för varje loop.
Loopen upprepas sålänge detta är sant: while(in.hasNextDouble())
...dvs så länge det finns fler inmatade tal att gå igenom.

Strängen cumulativeTotals printas inte ut förrens programmet når följande rad:
System.out.println(cumulativeTotals);

hmm. Hoppas det hjälper. Är rädd att jag kanske gjorde det rörigare istället.

Tack så mycket för snabbt svar. Tror definitivt inte att du gjorde det rörigare haha. Så om jag har fattat rätt så "lagras" de värden som användaren skriver in, och loopen hämtar ut dom en och en tills det inte finns fler tal att hämta?

Permalänk
Medlem
Skrivet av hawthorns:

Tack så mycket för snabbt svar. Tror definitivt inte att du gjorde det rörigare haha. Så om jag har fattat rätt så "lagras" de värden som användaren skriver in, och loopen hämtar ut dom en och en tills det inte finns fler tal att hämta?

Så kan man säga ja.
Ett tal i taget "processas" för varje omgång i loopen.
Först läggs det nya talet ihop till summan av dom tidigare talen på denna raden:
sum += input; //Lägger till input till summan(som börjar på 0)

Och sedan läggs talet till dom tidigare talen i strängen cumulativeTotals på denna raden:
cumulativeTotals = cumulativeTotals + " " + sum; //
Notera att mellanslaget " " är en sträng som även den läggs till.

Permalänk
Skrivet av FANTEN:

Så kan man säga ja.
Ett tal i taget "processas" för varje omgång i loopen.
Först läggs det nya talet ihop till summan av dom tidigare talen på denna raden:
sum += input; //Lägger till input till summan(som börjar på 0)

Och sedan läggs talet till dom tidigare talen i strängen cumulativeTotals på denna raden:
cumulativeTotals = cumulativeTotals + " " + sum; //
Notera att mellanslaget " " är en sträng som även den läggs till.

Perfekt, då förstår jag! Tack så mycket

Permalänk
99:e percentilen
Skrivet av hawthorns:

public static void main(String[] args) { Scanner in = new Scanner(System.in); System.out.println("Ange ett antal heltal."); String cumulativeTotals = ""; //Skapar stringen cumulativeTotals double sum = 0; //Sätter talsumman till 0 while(in.hasNextDouble()) { double input = in.nextDouble(); //Sätter värdet användaren skriver in till variabeln input sum += input; //Lägger till input till summan(som börjar på 0) cumulativeTotals = cumulativeTotals + " " + sum; // } System.out.println(cumulativeTotals); } }

Vad jag inte förstår är hur Stringen cumulativeTotals printar ut summan av talen efter varandra som i exemplet. Stringen assignas ju till " ", som kan ses som en tom string(eller?).

Ska försöka bidra med lite djupare förståelse.

Java är ett språk som har sidoeffekter som en central egenskap. En sidoeffekt kan man tänka är "något som händer". För att förstå vad det betyder kan man först betrakta följande tre uttryck (var för sig):

  • 5

  • "hello"

  • 10 + 2

Något de har gemensamt är att ingenting "händer" när de evalueras, alltså när man "tar reda på vad de har för värde". Med följande uttryck är det däremot en annan femma:

  • x = 5

Uttrycket 5 och uttrycket x = 5 har båda värdet 5. Men x = 5 har dessutom en sidoeffekt, nämligen att variabeln x (förutsatt att den finns; annars kompilerar inte x = 5) får värdet 5 tilldelat. Något "händer" när x = 5 evalueras, nämligen att x tilldelas ett nytt värde. Det är en typisk sidoeffekt.

I ditt fall har du raden

cumulativeTotals = cumulativeTotals + " " + sum;

som innehåller cumulativeTotals = …. Precis som x = 5 har det uttrycket en sidoeffekt, nämligen att tilldela ett nytt värde till variabeln cumulativeTotals. (Det nya värdet som tilldelas beror dessutom på vilket värde cumulativeTotals har just då.) Detta kan ske flera gånger under ditt programs körning, eftersom raden ligger inuti en loop.

När programmet väl kommer till satsen System.out.println(cumulativeTotals); kommer det värde som cumulativeTotals har att skrivas ut. Det är inte säkert att det är samma värde som cumulativeTotals först tilldelades (vilket som du säger är den tomma strängen).

Sidoeffekter är i praktiken nödvändiga för att skapa användbara program (annars kan man inte skriva ut någon output eller göra någonting annat som användaren märker), men kan också vara en källa till avsevärt huvudbry och förtvivlat knepiga buggar om de överanvänds.

Visa signatur

Skrivet med hjälp av Better SweClockers

Permalänk
Medlem

@hawthorns: Det är också en väldigt bra idé att lära dig hur debuggern fungerar i den utvecklingsmiljö du använder. Med den kan du stega igenom programmet medan det kör och se exakt vad som händer, vilket kommer hjälpa dig oerhört som nybörjare.

Permalänk

Tack så mycket för er hjälp, det är verkligen uppskattat. Jag har gått vidare i boken och kommit fram till en uppgift där jag med hjälp utav en for-loop ska printa ut en givet namn baklänges. Jag har kollat runt lite och sett flera exempel som har löst uppgiften på samma sak. Efter att ha läst runt och försökt med koden själv, så skrev jag av tre stycken av raderna, rad för rad, i hopp om att lyckas förstå mig på vad de betyder, men förstår inte riktigt hur for-loopen plockar ut stringen baklänges.
Istället för att skapa ett nytt inlägg så tänkte jag kolla om ni kunde kika på detta här istället. Koden lyder:

public static void main(String[] args) {
Scanner in = new Scanner(System.in);

System.out.println("Skriv in ett namn");
String input = in.next();

int length = input.length();

for (int i = length - 1; i >= 0; i--) {
char word = input.charAt(i);
System.out.print(word);
}

}

Permalänk
Medlem
Skrivet av hawthorns:

Tack så mycket för er hjälp, det är verkligen uppskattat. Jag har gått vidare i boken och kommit fram till en uppgift där jag med hjälp utav en for-loop ska printa ut en givet namn baklänges. Jag har kollat runt lite och sett flera exempel som har löst uppgiften på samma sak. Efter att ha läst runt och försökt med koden själv, så skrev jag av tre stycken av raderna, rad för rad, i hopp om att lyckas förstå mig på vad de betyder, men förstår inte riktigt hur for-loopen plockar ut stringen baklänges.
Istället för att skapa ett nytt inlägg så tänkte jag kolla om ni kunde kika på detta här istället. Koden lyder:

public static void main(String[] args) {
Scanner in = new Scanner(System.in);

System.out.println("Skriv in ett namn");
String input = in.next();

int length = input.length();

for (int i = length - 1; i >= 0; i--) {
char word = input.charAt(i);
System.out.print(word);
}
}

1. "input" är ett strängobjekt.
String input = in.next();

2. Strängobjektets metod length() returnerar antal tecken i strängen som en integer. Detta värde tilldelas variabeln length.
int length = input.length();

3. I for-loopen ser du att "i" sätts till length(dvs antal tecken som fanns i strängen). Så om det fanns 5 tecken i strängen så sätts i=5 till att börja med.
Loopen pågår sålänge "i" är större eller likamed length. i >= 0
För varje runda i loopen så räknas "i" ner med 1. i--
for (int i = length - 1; i >= 0; i--) {
...
}

4. I varje loop så sker följande.
Ett tecken läses ut från strängobjektet med hjälp av strängobjektets metod charAt(i) och tilldelas variabeln word. (T.ex. om i=5 så läses det 5:e tecknet ut och tilldelas till variabeln word.)
char word = input.charAt(i);
Följande rad skriver ut tecknet:
System.out.print(word);

Nästa runda i loopen så läses ett nytt tecken ut från strängen men nu så kommer i vara i=4 och då läses det 4:e tecknet ut och tilldelas till variabeln word. osv...

Permalänk
Skrivet av FANTEN:

1. "input" är ett strängobjekt.
String input = in.next();

2. Strängobjektets metod length() returnerar antal tecken i strängen som en integer. Detta värde tilldelas variabeln length.
int length = input.length();

3. I for-loopen ser du att "i" sätts till length(dvs antal tecken som fanns i strängen). Så om det fanns 5 tecken i strängen så sätts i=5 till att börja med.
Loopen pågår sålänge "i" är större eller likamed length. i >= 0
För varje runda i loopen så räknas "i" ner med 1. i--
for (int i = length - 1; i >= 0; i--) {
...
}

4. I varje loop så sker följande.
Ett tecken läses ut från strängobjektet med hjälp av strängobjektets metod charAt(i) och tilldelas variabeln word. (T.ex. om i=5 så läses det 5:e tecknet ut och tilldelas till variabeln word.)
char word = input.charAt(i);
Följande rad skriver ut tecknet:
System.out.print(word);

Nästa runda i loopen så läses ett nytt tecken ut från strängen men nu så kommer i vara i=4 och då läses det 4:e tecknet ut och tilldelas till variabeln word. osv...

Okej, då är det betydligt klarare vad loopen gör. Jag förstår att int = length hämtar ut längden på inputen. Men varför blir det int = length - 1 när det ändå står att den ska minskas på sista kommandot (i--).
Borde inte int = length - 1 hämta längden på inputen och ta bort med ett tecken direkt?

Exempelvis, om jag hade skrivit in "hej". Hade inte i satts till längden 2 istället för 3 då?

Permalänk
Medlem
Skrivet av hawthorns:

Exempelvis, om jag hade skrivit in "hej". Hade inte i satts till längden 2 istället för 3 då?

Java använder 0-baserade index, d.v.s. det första elementet i t.ex. en sträng har index 0 och inte 1. Så för en sträng med längd 3 har alltså första bokstaven index 0 och den sista index 2.

Notera också att int i = length - 1; initialiserar i innan loopen börjar loopa, medan i-- körs i slutet av varje iteration av loopen.

Permalänk
Skrivet av perost:

Java använder 0-baserade index, d.v.s. det första elementet i t.ex. en sträng har index 0 och inte 1. Så för en sträng med längd 3 har alltså första bokstaven index 0 och den sista index 2.

Notera också att int i = length - 1; initialiserar i innan loopen börjar loopa, medan i-- körs i slutet av varje iteration av loopen.

Ja juste! Precis som i en array. Det glömde jag.

Permalänk
Medlem

Oups. Missade det. Sorry.

Permalänk
Skrivet av FANTEN:

Oups. Missade det. Sorry.

Uppskattar hjälpen