Premiär! Fyndchans i SweClockers Månadens Drop
Permalänk
Medlem

Hjälp med Java tack.

Försöker skapa ett program som utför beräkningen 2^x, alltså 2 upphöjt till ett värde som jag ger skannern. Varje beräkning ska oxå sparas och sedan hämtas så att ej samma beräkning behöver utföras igen, det är detta som jag har problem med:

Hade verkligen uppskattat lite hjälp.

import java.util.HashMap; public class Model { HashMap<Integer,Long> memory = new HashMap<Integer,Long>(); Integer value; Long result; public long computePower(int value){ if(value <= 0 ) return 1; else{ return 2 * computePower(value-1); } } private void addValueToMemory(Integer value, Long result){ memory.put(value, result); } private Long getValueFromMemory(Integer value){ return memory.get(value); } public long compute2Power(int value){ if(value < 0) throw new IllegalArgumentException(); else if(value >= 0){ return getValueFromMemory(value); } else{ return computePower(value); } } public void clearMemory(){ memory.clear(); } }

import java.util.Scanner; public class Program { public static void main(String[] args) { Model m = new Model(); Scanner s = new Scanner(System.in); System.out.println("Add a positive number, -1 to clear or -2 to quit"); int input = 0; while(input != -2){ input = s.nextInt(); if(input == -1){ m.clearMemory(); System.out.println("Memory cleared"); } else if(input == -2){ m.clearMemory(); System.out.println("Memory cleared"); System.out.println("Program quits"); } else if(input >= 0){ System.out.println("2^n = " + m.compute2Power(input)); } else{ try{ System.out.println("Invalid input"); }catch(IllegalArgumentException e){ } } } System.exit(0); } }

Här är fellmedelandet:

Exception in thread "main" java.lang.NullPointerException
at Model.compute2Power(Model.java:32)
at Program.main(Program.java:31)

rad 32 i klassen model är: return getValueFromMemory(value);

rad 31 i main klassen Program är :System.out.println("2^n = " + m.compute2Power(input));

Även den här raden: private void addValueToMemory(Integer value, Long result){
memory.put(value, result);
är understruken med texten: The method addValueToMemory(Integer, Long) from the type Model is never used locally .

Permalänk
Medlem
Skrivet av floomer:

Försöker skapa ett program som utför beräkningen 2^x, alltså 2 upphöjt till ett värde som jag ger skannern. Varje beräkning ska oxå sparas och sedan hämtas så att ej samma beräkning behöver utföras igen, det är detta som jag har problem med:

Hade verkligen uppskattat lite hjälp.

import java.util.HashMap; public class Model { HashMap<Integer,Long> memory = new HashMap<Integer,Long>(); Integer value; Long result; public long computePower(int value){ if(value <= 0 ) return 1; else{ return 2 * computePower(value-1); } } private void addValueToMemory(Integer value, Long result){ memory.put(value, result); } private Long getValueFromMemory(Integer value){ return memory.get(value); } public long compute2Power(int value){ if(value < 0) throw new IllegalArgumentException(); else if(value >= 0){ return getValueFromMemory(value); } else{ return computePower(value); } } public void clearMemory(){ memory.clear(); } }

import java.util.Scanner; public class Program { public static void main(String[] args) { Model m = new Model(); Scanner s = new Scanner(System.in); System.out.println("Add a positive number, -1 to clear or -2 to quit"); int input = 0; while(input != -2){ input = s.nextInt(); if(input == -1){ m.clearMemory(); System.out.println("Memory cleared"); } else if(input == -2){ m.clearMemory(); System.out.println("Memory cleared"); System.out.println("Program quits"); } else if(input >= 0){ System.out.println("2^n = " + m.compute2Power(input)); } else{ try{ System.out.println("Invalid input"); }catch(IllegalArgumentException e){ } } } System.exit(0); } }

Här är fellmedelandet:

Exception in thread "main" java.lang.NullPointerException
at Model.compute2Power(Model.java:32)
at Program.main(Program.java:31)

rad 32 i klassen model är: return getValueFromMemory(value);

rad 31 i main klassen Program är :System.out.println("2^n = " + m.compute2Power(input));

Även den här raden: private void addValueToMemory(Integer value, Long result){
memory.put(value, result);
är understruken med texten: The method addValueToMemory(Integer, Long) from the type Model is never used locally .

compute2Power()/getValueFromMemory() kollar aldrig om resultatet för det efterfrågade värdet tidigare har sparats. getValueFromMemory() returnerar med andra ord alltid ett null för alla värden större eller likamed 0. Detta null blir till ett exception i compute2Power när den unboxar Long till long.

Ang. att raden är understruken: det är bara en hjälpande varningseffekt från din utvecklingsmiljö. Du borde få samma varning på rad 6 och 7 i Model.java

Visa signatur

Kom-pa-TI-bilitet

Permalänk
Medlem

Ok tack för din hjälp. Så vad exakt måste jag skriva för att metoden ska fungera?

Permalänk
Medlem
Skrivet av floomer:

Ok tack för din hjälp. Så vad exakt måste jag skriva för att metoden ska fungera?

En stor del i att lära sig programmera är att själv lösa problem man får. Nu vet du exakt vad problemet är, att säga exakt vad du ska ändra är en björntjänst.

Visa signatur
Permalänk
Medlem
Skrivet av floomer:

Ok tack för din hjälp. Så vad exakt måste jag skriva för att metoden ska fungera?

Börja med att förklara hur du tänkte här:

public long compute2Power(int value) { if(value < 0) throw new IllegalArgumentException(); else if(value >= 0){ return getValueFromMemory(value); } else{ return computePower(value); } }

Om value är mindre än noll så är det en IllegalArgumentException, om value är noll eller högre hämtar du det från minnet. I vilken situation kommer "return computePower(value)" hända?

Visa signatur

Fractal Design Define R5 | MSI Z97-GD65 Gaming | MSI Geforce GTX 970 Gaming 4G | Intel i5 4690k | Cooler Master Hyper 212 EVO | EVGA Supernova G2 750W | 2x8GB Corsair Vengeance Low Profile DDR3 1600Mhz | Samsung 850 EVO | Seagate 1TB SATA3.5

Permalänk
Medlem

Vad är ens poängen med HashMap:en?
Sedan bör du nog fundera lite över hur du beräknar upphöjt:

return 2 * computePower(value-1);

Visa signatur

2600k @ STOCK <|> GTX 970 Omega!<|> Nån samsung 500gb ssd <|> 16 GB Kingston Hyper X <|> BenQ XL2420t
"Det finns inget skrot, bara gamla delar som kan användas på nya sätt" - Mulle Meck

Permalänk
Medlem
Skrivet av elklazor:

Vad är ens poängen med HashMap:en?
Sedan bör du nog fundera lite över hur du beräknar upphöjt:

return 2 * computePower(value-1);

HashMapen ska fungera som själva cache-minnet.

Angående upphöjt så fungerar den metoden alldeles utmärkt. Då kravet var att det skulle beräknas rekursivt och man ej fick använda math.pow.

Permalänk
Medlem
Skrivet av Thornblom:

En stor del i att lära sig programmera är att själv lösa problem man får. Nu vet du exakt vad problemet är, att säga exakt vad du ska ändra är en björntjänst.

Jo jag förstår det *skäms* Ibland tar tålamodet slut dock..
Går en grundkurs i programmering och har klarat de flesta övningsuppgiftera utan större bekymmer på egen hand. Känns som den här uppgiften lirar i en lite högre division än vad vi befinner oss.

Permalänk
Medlem
Skrivet av Tobberoth:

Börja med att förklara hur du tänkte här:

public long compute2Power(int value) { if(value < 0) throw new IllegalArgumentException(); else if(value >= 0){ return getValueFromMemory(value); } else{ return computePower(value); } }

Om value är mindre än noll så är det en IllegalArgumentException, om value är noll eller högre hämtar du det från minnet. I vilken situation kommer "return computePower(value)" hända?

Ja visst tusan.. Jag tog för givet dumt nog att fanns det inget i minnet skulle programmet hoppa vidare. Den stora frågan för mig nu är bara vilket förhållande som ska ges till sista else if.. ? typ något i stil med ... else if(value == 0); else if(getValueFromMemory(value == 0); hmm..

Permalänk
Medlem
Skrivet av floomer:

Ja visst tusan.. Jag tog för givet dumt nog att fanns det inget i minnet skulle programmet hoppa vidare. Den stora frågan för mig nu är bara vilket förhållande som ska ges till sista else if.. ? typ något i stil med ... else if(value == 0); else if(getValueFromMemory(value == 0); hmm..

Som jag ser det bör du fokusera på själva logiken snarare än hur koden skall se ut. Din kod vill hämta värdet som det finns i minnet, annars räkna ut det. Utöver detta vill funktionen också reagera om värdet inte är valid. Nu är det bara att bygga koden runt den logiken:

public long compute2Power(int value) { if (value < 0) throw new IllegalArgumentException(); Long ret = getValueFromMemory(value); if (ret != null) return (long)ret; else return computePower(value); }

Varning, jag har inte jobbat med Java på länge och är inte superinsatt i hur boxing och nullables fungerar. Jag antar att Long är som en nullable long och kan castas till long, i så fall borde koden ovan fungera. Det är snarare logiken som är det viktiga dock, inte exakt hur det är skrivet.

Visa signatur

Fractal Design Define R5 | MSI Z97-GD65 Gaming | MSI Geforce GTX 970 Gaming 4G | Intel i5 4690k | Cooler Master Hyper 212 EVO | EVGA Supernova G2 750W | 2x8GB Corsair Vengeance Low Profile DDR3 1600Mhz | Samsung 850 EVO | Seagate 1TB SATA3.5

Permalänk
Datavetare

Dela upp det i två delar, en som alltid tar resultatet ur minnet och som därmed måste lägga till de resultat som saknas. Den andra delen är att räkna ut resultat utan hänsyn taget till eventuell cache.

Det första steget blir då något i linje med detta

static public Long memoize(Integer arg) { if (!cache.containsKey(arg)) { cache.put(arg, compute(arg)); } return cache.get(arg); }

där "cache" är en instans av din HashMap<Integer, Long> och "compute" är det som alltid räknar ut resultatet.

Visa signatur

Care About Your Craft: Why spend your life developing software unless you care about doing it well? - The Pragmatic Programmer