Permalänk
Medlem

java problem, parametrar.

hej jag har ett problem med en class jag håller på att skapa. Jag hoppas någon kan hjälpa mig!

i main anropar jag följande: Util.slumpOrdning(a); //a är ett fält
jag vill då att elementen i a ska hamna på slumpade positioner i fältet.

Elementen i flt i klassen Util får slumpade positioner. Så den biten är det nog inget fel på .Mitt problem är att elementen i a har samma possitioner som innan annropet! hur ska jag skriva för att a ska påverkas??

public static void slumpOrdning(Object[] flt){ // detta är fel?

public static void slumpOrdning(Object[] *flt){ // det borde kanske vara så elelr på nått liknande sett( så gör man i c++ om jag inte mins helt fel)

KOD:

public class Util {
public static void slumpOrdning(Object[] flt){
int feltlengd=flt.length , k=-1;
Object flt_temp[]=new Object [feltlengd];
int flt_slumptal[]= new int [feltlengd];
Boolean lika=false;

while(k!=feltlengd-1){

Random generator = new Random();
int slumptal =generator.nextInt(feltlengd); //slumpar tal

for(int i=0;i!=feltlengd-1;i++){ //kollar om det slumpade talet
if(flt_slumptal[i]==slumptal) //redan använts
lika=true;
}

if(lika!=true){
k++;
flt_slumptal[k]=slumptal;
flt_temp[k]=flt[slumptal];
}

lika=false;
}

flt= flt_temp.clone();
}
}

Visa signatur

jo det är jag

Permalänk
Medlem

Lagra talen i någon form av List istället, typ en ArrayList. Sen använder du java.util.Collections.shuffle(List).
Exempel:

import java.util.Collections; ... ArrayList<Integer> arrayList = new ArrayList<Integer>(); arrayList.add(new Integer(1)); arrayList.add(new Integer(25)); arrayList.add(new Integer(75)); Collections.shuffle(arrayList); ...

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av bjornie
Lagra talen i någon form av List istället, typ en ArrayList. Sen använder du java.util.Collections.shuffle(List).
Exempel:

import java.util.Collections; ... ArrayList<Integer> arrayList = new ArrayList<Integer>(); arrayList.add(new Integer(1)); arrayList.add(new Integer(25)); arrayList.add(new Integer(75)); Collections.shuffle(arrayList); ...

ArrayList är mer krävande än vanliga arrays, det går att snabba upp programmet om man gör grejerna själv istället. Speciellt om det är många fält i ens array.

Citat:

Ursprungligen inskrivet av joquitch
hej jag har ett problem med en class jag håller på att skapa. Jag hoppas någon kan hjälpa mig!

i main anropar jag följande: Util.slumpOrdning(a); //a är ett fält
jag vill då att elementen i a ska hamna på slumpade positioner i fältet.

Elementen i flt i klassen Util får slumpade positioner. Så den biten är det nog inget fel på .Mitt problem är att elementen i a har samma possitioner som innan annropet! hur ska jag skriva för att a ska påverkas??

public static void slumpOrdning(Object[] flt){ // detta är fel?

public static void slumpOrdning(Object[] *flt){ // det borde kanske vara så elelr på nått liknande sett( så gör man i c++ om jag inte mins helt fel)

KOD:

public class Util {
public static void slumpOrdning(Object[] flt){
int feltlengd=flt.length , k=-1;
Object flt_temp[]=new Object [feltlengd];
int flt_slumptal[]= new int [feltlengd];
Boolean lika=false;

while(k!=feltlengd-1){

Random generator = new Random();
int slumptal =generator.nextInt(feltlengd); //slumpar tal

for(int i=0;i!=feltlengd-1;i++){ //kollar om det slumpade talet
if(flt_slumptal[i]==slumptal) //redan använts
lika=true;
}

if(lika!=true){
k++;
flt_slumptal[k]=slumptal;
flt_temp[k]=flt[slumptal];
}

lika=false;
}

flt= flt_temp.clone();
}
}

Anropa enligt följande:

a = Util.slumpOrdning(a);

------

Java har inte pointers som i C++, det finns sätt att komma runt detta om man måste ha funktionalitet liknande pointers. Jag rekommenderar att du gör som jag skrev. Många säger att allt i Java är pointers då till exempel undantaget NullPointerException finns. Java har i alla fall inte C++ pointers, om man säger så.

Alternativt kan du skapa en egen klass som heter kanske Lista som beskriver din "a" och har en metod som heter slumpOrdning().

Det är svårt att lösa problemet på andra sätt då jag/vi inte vet mer av koden och hur hela applikationen ser ut.

Hoppas du blev klokare.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Leedow
ArrayList är mer krävande än vanliga arrays, det går att snabba upp programmet om man gör grejerna själv istället. Speciellt om det är många fält i ens array.

Gha. Vad får folk sina dumma idéer ifrån? Ja, en array är marginellt snabbare vid insert's. Men hur mycket tror du att trådskaparen bryr sig om prestanda? Han vill antagligen lära sig programmera på ett bra sätt. Och för övrigt tror jag att du tjänar ihop de millisekunder som du förlorar på insert's till en List, när du använder Collections.shuffle() istället för att skriva ihop en egen metod med två for-slingor, en massa overhead-variabler, m.m. Jeez, lär dig programmera...

Permalänk
Citat:

Ursprungligen inskrivet av bjornie
Gha. Vad får folk sina dumma idéer ifrån? Ja, en array är marginellt snabbare vid insert's. Men hur mycket tror du att trådskaparen bryr sig om prestanda? Han vill antagligen lära sig programmera på ett bra sätt. Och för övrigt tror jag att du tjänar ihop de millisekunder som du förlorar på insert's till en List, när du använder Collections.shuffle() istället för att skriva ihop en egen metod med två for-slingor, en massa overhead-variabler, m.m. Jeez, lär dig programmera...

Om man dessutom vet antal tal som man vill stoppa in i ArrayList:en så lär det inte skilja mycket då underliggande struktur för ArrayList ändå är en array. Håller med dig. TS bör använda ditt förslag.

Visa signatur

Om man tänker en tanke, så är den tanken inte den tanke man tror att man tänker. Utan det är den tanke som får en att tro att man tror den tanke man tror att man tänker.

Permalänk
Medlem

Ni har ju kommit med lösningar som säkert fungerar, men ingen verkar gå hand i hand med uppgiften.

Uppgift (deluppgift)

Din uppgift är därför nu att konstruera en klassmetod med namnet slumpOrdning. Metoden skall läggas i en separat klass med namnet Util. Metoden skall ha resultattypen void. Som enda parameter skall den ha ett fält där elementen är av typen Object (dvs. ett fält som kan innehålla referenser till objekt av vilken klass om helst.). När metoden anropas skall den placera om elementen i fältet på ett slumpmässigt sätt.

Tips. Använd ett temporärt fält inne i metoden och plocka ut ett element i taget från det ursprungliga fältet och placera in det på ett slumpmässigt ställe i det temporära fältet. Om platsen redan är upptagen måste du förstås slumpa fram en ny plats. När alla elementen är utplacerade kan du sedan kopiera det temporära fältet till det ursprungliga.

När klassen Util med sin klassmetod slumpOrdning är klar skall den testas med hjälp av det färdiga testprogrammet Slumptest.

----
Det vesentliga i Slumptest ser ut på följande vis:

Util.slumpOrdning(a);

for (int i = 0; i < a.length; i++)
System.out.print(a[i] + " ");

...därför funkar ju inte a=Util.slumpOrdning(a); , eftersom jag itne ska ändra på detta program!

Visa signatur

jo det är jag

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av joquitch
...därför funkar ju inte a=Util.slumpOrdning(a); , eftersom jag itne ska ändra på detta program!

Tanken är inte att du ska skriva så, utan bara Util.slumpOrdning(a);. Meningen är att a ska ändras in-place, dvs fältet du skickar in kommer att manipuleras direkt, du får inte någon manipulerad kopia tillbaka som returvärde. Den första metodsignaturen du angav, public static void slumpOrdning(Object[] flt), ska fungera fint.

Citat:

Ursprungligen inskrivet av joquitch
Tips. Använd ett temporärt fält inne i metoden och plocka ut ett element i taget från det ursprungliga fältet och placera in det på ett slumpmässigt ställe i det temporära fältet. Om platsen redan är upptagen måste du förstås slumpa fram en ny plats. När alla elementen är utplacerade kan du sedan kopiera det temporära fältet till det ursprungliga.

Tycker jag verkar som en onödigt jobbig och trög algoritm. Det kan ta väldigt lång tid att slumpa fram de sista lediga platserna om det är ett stort fält. Vad är det för en dårfink som lär ungar att programmera på det sättet?

När jag lärde mig att göra motsvarande grejor som liten pojk så använde jag följande algoritm:

* Vandra igenom fältet linjärt, element för element. Kalla aktuellt index för i.
* Slumpa fram en nytt, godtyckligt index i fältet, kalla det j.
* Byt plats på värdena på positionerna i och j.

Permalänk
Citat:

Ursprungligen inskrivet av Leedow
ArrayList är mer krävande än vanliga arrays, det går att snabba upp programmet om man gör grejerna själv istället. Speciellt om det är många fält i ens array.

Är det inte bättre att använda en datastruktur som löser problemet på ett enkelt sätt, och sedan byta ut den om det under profilering skulle visa sig att det är en verklig flaskhals?

Visa signatur

"I cannot. Yet I must. How do you calculate that? At what point on the graph do 'must' and 'cannot' meet? Yet I must. But I cannot."

Permalänk
Medlem

Jag har nu ett nytt problem, vi glömmer problemet med slumpOrdning!

Nedan kan ni se mitt huvud program. Det går fin att kompilerar men när jag kör det visas följande felmedelande efter att jag skrivit in antal rader och kolumner!
felmedelandet:

Exception in thread "main" java.lang.NullPointerException
at Memory.<init>(Memory.java:21)
at Memory.main(Memory.java:64)

---------

import java.awt.*; //rad 1.
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class Memory extends JFrame implements ActionListener{
public Kort k[];
public Kort[] flt_spelkort;
public int n, kol,rad;

public Memory(int rader, int kolumner){
rad=rader;
kol=kolumner;
File bildmapp = new File("bildmapp");
File[] bilder = bildmapp.listFiles();
for(int i=0;i<bilder.length;i++){
String adr = bilder[i].getPath();
k[i] = new Kort(new ImageIcon(adr),Kort.Status.DOLT);
}

nyttspel(); //rad 21.
}

public void nyttspel(){
n=rad*kol;
Util.slumpOrdning(k);

for(int i=0;i<n/2;i++){
flt_spelkort[i]=k[i];
}
for(int i=0;i<n/2;i++){
flt_spelkort[i+n/2]=k[i];
}

Util.slumpOrdning(flt_spelkort);
Container c =getContentPane();
c.setLayout(new GridLayout(rad, kol));
c.setBackground(Color.white);
for(int i=0;i<n;i++){
c.add(flt_spelkort[i]);
flt_spelkort[i].addActionListener(this);
}

setVisible(true);
}

public void actionPerformed(ActionEvent e) {
for(int i=0;i<n;i++){
if(e.getSource() == flt_spelkort[i])
flt_spelkort[i].setStatus(Kort.Status.SYNLIGT);
}
}

public static void main(String[] arg) {
int rader=0, kolumner=0;
String s_rader=JOptionPane.showInputDialog("antal rader:");
String s_kolumner=JOptionPane.showInputDialog("antal kolumner:");
rader=Integer.parseInt(s_rader);
kolumner=Integer.parseInt(s_kolumner);
Memory m=new Memory(rader, kolumner);
}
}

-----

Det kanske är svårt att hitta felet då ni inte har alla klasser och så! men någon kanske kan se nått i denna kod som verkar skumt? de andra klasserna ska det iaf inte vara något fel i.

Det är en början till ett memory-spel, men dock inte fullbordat! jag vill att denna kod ska fungera innan jag går vidare!

tack på förhand // J

Visa signatur

jo det är jag

Permalänk
Medlem

Det är inte rimligt att anropet till nyttspel() ska generera en NullPointerException. Jag skulle istället gissa på att det är raden

String adr = bilder[i].getPath();

som ställer till det. Det kan vara så att "bildmapp" inte är en korrekt angiven sökväg, så listFiles() returnerar null och följaktligen är bilder-fältet inte ett fält, utan bara null.

Och använd code-taggar nästa gång du lägger in kod på forumet, tack.

Permalänk
Medlem

okej, tack! jag ska testa att greja med det du just nämde!

jag försökte , men jag ltckades aldrig få till "code-taggar".. hur gör man? vad skriver man?

EDIT:

jag prövade att ändra koden till följande:

File bildmapp = new File("D:\\Documents and Settings\\joakim\\bildmapp");

men det gjorde ingen skillnad! det ligger 2 bilder i den mappen..

EDIT2:

Jag har kommit fram till vad det är som är problemet!

Det är inte tillåtet att skriva : public Kort[] k = new Kort();

felmedelande:

incompatible types
found: Kort
required: kort[]
public Kort[] k = new Kort();

---
Hur kan detta komma sig?
Hur ska jag göra för att kunna ha "kort" i ett fält?

Visa signatur

jo det är jag

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av bjornie
Gha. Vad får folk sina dumma idéer ifrån? Ja, en array är marginellt snabbare vid insert's. Men hur mycket tror du att trådskaparen bryr sig om prestanda? Han vill antagligen lära sig programmera på ett bra sätt. Och för övrigt tror jag att du tjänar ihop de millisekunder som du förlorar på insert's till en List, när du använder Collections.shuffle() istället för att skriva ihop en egen metod med två for-slingor, en massa overhead-variabler, m.m. Jeez, lär dig programmera...

Du bekräftar allt jag säger även om det är marginellt, men ska även förolämpa mig. Vad vill du ha sagt?
Han har ju tydligen gjort egen kod, kan ju vara kul att köra egen kod och inte färdig kod. Det enda sättet att lära sig på.
Collections.shuffle() har också två loopar, viktigpetter.

Citat:

Ursprungligen inskrivet av Ulrik Uppkastare
Är det inte bättre att använda en datastruktur som löser problemet på ett enkelt sätt, och sedan byta ut den om det under profilering skulle visa sig att det är en verklig flaskhals?

Det köper jag.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av joquitch
EDIT2:

Jag har kommit fram till vad det är som är problemet!

Det är inte tillåtet att skriva : public Kort[] k = new Kort();

felmedelande:

incompatible types
found: Kort
required: kort[]
public Kort[] k = new Kort();

---
Hur kan detta komma sig?
Hur ska jag göra för att kunna ha "kort" i ett fält?

Eh, jag förstår inte hur det kan vara det som orsakade problemet tidigare, när det inte fanns i koden ovan. Och först hade du ett nullpointerexception, nu har du kod som inte kompilerar.

I alla fall.
För att deklarera ett fält behöver du ange hur stort det ska vara, likt:

public Kort[] k = new Kort[16];

...eller hur många element du nu vill att fältet ska ha.

Dessutom måste du, efter att ha definierat dess storlek, placera objekt i fältet. Från början innehåller ett fält endast null-referenser.

Permalänk

import java.util.Random; public class Main { public static void main ( String[] args ) { // Alla färger. String[] suites = { "Hearts", "Spades", "Diamonds", "Clubs" }; // Alla valörer. String[] numbers = { "Ace", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Knight", "Queen", "King" }; // Här ska vi spara alla korten. String[] cards = new String[52]; // Räknare för vilket kort vi lägger in. int card = 0; for ( int i = 0; i < suites.length; i ++ ) for ( int j = 0; j < numbers.length; j ++ ) { // Lägg in ett kort med rätt färg och valör, cards[card] = numbers[j] + " of " + suites[i]; // Se till så att vi lägger in nästa kort. card = card + 1; } // Blanda alla kort. Shuffle ( cards ); // Skriv ut alla korten. for ( String s : cards ) System.out.println ( s ); } // Byt plats på korten. public static void Shuffle ( String[] cards ) { Random rand = new Random (); int n = cards.length; while ( n > 1 ) { int k = rand.nextInt ( n ); n = n - 1; // Byt ut kortet som finns på plats n mot kortet // som finns på plats k och kortet som finns på // plast k mot kortet som finns på plats n. String temp = cards[n]; cards[n] = cards[k]; cards[k] = temp; } } }

Vet inte, kanske ger dig en rejäl skjuts framåt.
Blandningsalgoritmen som används heter Fisher-Yates Shuffle eller Knuth Shuffle.

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av Leedow
Du bekräftar allt jag säger även om det är marginellt, men ska även förolämpa mig. Vad vill du ha sagt?
Han har ju tydligen gjort egen kod, kan ju vara kul att köra egen kod och inte färdig kod. Det enda sättet att lära sig på.
Collections.shuffle() har också två loopar, viktigpetter.

Sorry, var på grymt dåligt humör hela dagen. Jag menar egentligen inte att vara besserwisser. Men faktum är att alltför ofta då man rekommenderar folk att använda Collections och Listor istället för arrayer, så får man en liknande kommentar som du gav. Collection och Listor ger mer funktionalitet än arrayer out of the box, är enklare att manipulera och allmänt vedertaget att man _ska_ använda dem så länge man inte ser att det är en flaskhals och att den funktionalitet som kommer med dom inte används. Och jag insåg inte att det var en skoluppgift TS gjorde, där han skulle skriva en egen shuffle-metod. Så, ledsen för att jag var grinig. Men faktum kvarstår att Collections och Listor ska man använda så långt det går, eftersom att det underlättar arbetet och uppföljning av det.

Permalänk
Medlem

Nu behöver jag verkligen hjälp med klassen "Util" nedan ser ni lite tips och så om hur man ska göra!

Om jag skriver:
Util.SlumpOrdning(a);
...då ska elementen i a fått nya possitioner( a är ett fält, en array).

-----
Klassen Util

I programmet behöver man slumpmässigt välja vilka bilder som skall användas och man behöver också placera ut dem på ett slumpmässigt sätt i fönstret. Då kan man ha nytta av en metod som flyttar om elementen i ett fält på ett slumpmässigt sätt. Din uppgift är därför nu att konstruera en klassmetod med namnet slumpOrdning. Metoden skall läggas i en separat klass med namnet Util. Metoden skall ha resultattypen void. Som enda parameter skall den ha ett fält där elementen är av typen Object (dvs. ett fält som kan innehålla referenser till objekt av vilken klass om helst.). När metoden anropas skall den placera om elementen i fältet på ett slumpmässigt sätt.

Tips. Använd ett temporärt fält inne i metoden och plocka ut ett element i taget från det ursprungliga fältet och placera in det på ett slumpmässigt ställe i det temporära fältet. Om platsen redan är upptagen måste du förstås slumpa fram en ny plats. När alla elementen är utplacerade kan du sedan kopiera det temporära fältet till det ursprungliga.

------

min kod:
-----------

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.text.*;
import java.lang.*;

public class Util {
public static void slumpOrdning(Object[] flt){
int feltlengd=flt.length , k=-1;

Object flt_temp[]=new Object [feltlengd];
int flt_slumptal[]= new int [feltlengd];

Boolean lika=false;

while(k!=feltlengd-1){
Random generator = new Random();
int slumptal =generator.nextInt(feltlengd);

for(int i=0;i!=feltlengd-1;i++){
if(flt_slumptal[i]==slumptal)
lika=true;
}

if(lika!=true){
k++;
flt_slumptal[k]=slumptal;
flt_temp[k]=flt[slumptal];
}

lika=false;
}
flt= flt_temp.clone();

}
}
---------------------

förlåt , jag vet itne hur man gör "snygg kod-text"

Visa signatur

jo det är jag

Permalänk
Medlem

Felet består i den sista raden. För att få den nya ordningen placerad i flt så måste du kopiera över element för element från flt_temp. Det tror jag du fixar utan att jag behöver visa det med kod.

Eller så kan man göra på ett helt annorlunda och bättre sätt. Men gör du ändringen ovan så fungerar det iaf. För om sanningen ska fram så är detta inte bra:

Citat:

Ursprungligen inskrivet av joquitch
Tips. Använd ett temporärt fält inne i metoden och plocka ut ett element i taget från det ursprungliga fältet och placera in det på ett slumpmässigt ställe i det temporära fältet. Om platsen redan är upptagen måste du förstås slumpa fram en ny plats. När alla elementen är utplacerade kan du sedan kopiera det temporära fältet till det ursprungliga.

Säg mig, går du någon programmeringskurs på gymnasiet eller nåt, och har fått de här instruktionerna från din lärare? Du kan då vänligt hälsa din lärare från farbror badboll att han/hon är inte är lämpad att lära ut programmering. Algoritmen som beskrivs ovan är fullkomligt idiotisk av två skäl:

1) Du arbetar på ett dubblerat fält HELT i onödan, eftersom nettoeffekten av metoden ÄNDÅ ska vara att omkastningen av värdena sker i det fält du skickat in. De extra få byte det handlar om i det här fallet är inget att bråka om, men principiellt är det onödigt. Värre är:

2) Algoritmen är icke-deterministisk, dvs man kan inte på förhand avgöra hur länge den kör, hur många varv vi måste köra i while-loopen. Du kan själv stoppa in en räknarvariabel som ökar med ett för varje varv, och skriva ut den när loopen är färdig för att se själv. Körningstiden har ingen övre gräns som beror på hur stort fält man skickar in, utan det är egentligen bara tur att den förr eller senare kör klart. Sådana algoritmer ska undvikas som pesten.

Ja, datorer är snabba, Java är tämligen snabbt och vi arbetar på så små datamängder att det i vårt fall inte spelar någon roll. Men dåliga vanor grundläggs tidigt, och det är helt förkastligt att sådana lärs ut i skolan av inkompetenta lärare. (Även om det tyvärr sker hela tiden. ) Det är fan bättre att de inte försöker lära ut nånting alls.

Citat:

förlåt , jag vet itne hur man gör "snygg kod-text"

Du skriver [ code ] din kod [ /code ], fast utan mellanrummen mellan klamrarna och code respektive /code.

Permalänk
Medlem

tackar:)

HeHe jag läser Object Orienterad programering på Chalmers , jag får helt enkelt ta och medela Jan Skansholm detta^^ för jag tror på dig!

Visa signatur

jo det är jag

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av joquitch
tackar:)

HeHe jag läser Object Orienterad programering på Chalmers , jag får helt enkelt ta och medela Jan Skansholm detta^^ för jag tror på dig!

Herregud. :-S Jag som levde under illusionen att Skansholm skrev bra, eller åtminstone ok, böcker. Om citatet ovan är direkt saxat ur boken och det inte finns någon notis eller anvisning om att det är en KASS algoritm i dess direkta närhet - ja, då ska karln baske mig ha stryk. Det är faktiskt direkt oansvarigt av honom att skriva så i en bok tänkt för nybörjare som inte vet bättre. Usch.

Lycka till med memoryspelet iaf!

Permalänk
Medlem
Citat:

Ursprungligen inskrivet av bjornie
Sorry, var på grymt dåligt humör hela dagen. Jag menar egentligen inte att vara besserwisser. Men faktum är att alltför ofta då man rekommenderar folk att använda Collections och Listor istället för arrayer, så får man en liknande kommentar som du gav. Collection och Listor ger mer funktionalitet än arrayer out of the box, är enklare att manipulera och allmänt vedertaget att man _ska_ använda dem så länge man inte ser att det är en flaskhals och att den funktionalitet som kommer med dom inte används. Och jag insåg inte att det var en skoluppgift TS gjorde, där han skulle skriva en egen shuffle-metod. Så, ledsen för att jag var grinig. Men faktum kvarstår att Collections och Listor ska man använda så långt det går, eftersom att det underlättar arbetet och uppföljning av det.

Tack för uppklarningen.

Visa signatur

ηλί, ηλί, λαμά σαβαχθανί!?