[Java] Hjälp med egen compareTo

Permalänk
Medlem

[Java] Hjälp med egen compareTo

Hej

Håller på att försöka lösa en uppgift, men det går tungt.
Uppgiften är följande: Läs in de olika löparnas resultat, och skriv ut ett sorterad lista för varje tävling (det snabbaste resultatet först).

Indata :först ett tal som anger antalet löpare, följt av annat tal som anger antal tävlingar. Sedan följer varje löpares resultat: Först löparens förnamn, följt av ett heltal k som anger antalet resultat, följt av resultaten specificerade som k par av tal som i exemplet ovan. (varje indata är på en ny rad)

Utdata: Först ska tävlings nummer skrivas ut, följt av resultaten i tidsordning. Om flera personer har samma tid skriv de ut i alfabetisk ordning.

Jag försöker definiera en compareTo som utifrån dessa krav ska kunna sortera arrayen. Frågan är även hurvida en 2d array är det bästa sättet?
Känner mig bara helt vilse i pannkakan för tillfället, även om den kompilerar koden verkar min compareTo inte funka.
Hoppas någon har lust att ge lite tips, så det blir någon julfrid

import java.util.*; import java.lang.*; class Resultat implements Comparable<Resultat> { String namn; double tid; public Resultat( String n, double t ) { namn = n; tid = t; } public String toString() { return namn + ","+ tid; } public int compareTo( Resultat r ) { if (this.tid < r.tid){ return -1; } else if (this.tid > r.tid){ return 1; } else if (this.tid == r.tid && this.namn.compareTo(r.namn) >= 0) { return -1; } else if ( this.tid == r.tid && this.namn.compareTo(r.namn) <= 0){ return 1; } else {return 0;} } } public class jogging { public static void main( String[] args ){ Scanner scan = new Scanner(System.in); //antal löpare int runners = scan.nextInt(); //if max 100 //antal tävlingar int competitions = scan.nextInt(); //skapa array Resultat [][] res = new Resultat[competitions][runners]; for (int i = 0; i < runners; i++){ String name = scan.next(); //antal tävlingar personen deltog i int antalruns = scan.nextInt(); for(int n = 0; n <antalruns; n++){ //tävlingens nummer int compnumber = scan.nextInt(); //tiden för tävlingen double time = scan.nextDouble(); //lägg till objektet res[compnumber][i] = new Resultat(name,time); } } //test Arrays.sort(res); System.out.println(res[0][0]); System.out.println(res[0][1]); } }

Permalänk
Medlem

Skulle väl i princip aldrig rekommendera en 2d-array utan håll dig till javas generiska listor.
Har int kollat igenom din kod helt med om du tex ska ha olika tävlingar och dessa ska vara sorterade inbördes, så kan du tex ha en map med tävlingsnamnet som key och en lista med deltagare.

HashMap<String, TreeSet<Runner> >

Runner kan du vara din klass med name och tid tex.

Ett TreeSet ser till att din lista är sorterad, men då behöver du skicka in en egen comparator när du skapar den.
En egen comparator är väldigt lätt att skapa och ser i princip ut som din compareTo metod.

Permalänk
Medlem

Borde du inte snarare göra något i stil med

for (int i = 0; i < res.length; ++i) { Arrays.sort(res[i]); }

Permalänk
Medlem
Skrivet av Scones:

public int compareTo( Resultat r ) { if (this.tid < r.tid){ return -1; } else if (this.tid > r.tid){ return 1; } else if (this.tid == r.tid && this.namn.compareTo(r.namn) >= 0) { return -1; } else if ( this.tid == r.tid && this.namn.compareTo(r.namn) <= 0){ return 1; } else {return 0;} } }

compareTo borde väl ta ett Object o som inparameter för att fungera? Detta görs lättast med att du typecastar ditt o till ett Resultatobjekt efter en koll om o är ett Resultatobjekt.
Kort halvpseudokod

public int compareTo( Object o ) { Kontrollera om o är resultatobjekt Om o är resultatobjekt, genomför jämförelsen Om o inte är resultatobjekt, kasta exception }

Kan även tillägga att i de fallet att tiden är densamma räcker det att du returnerar namn.compareTo((Resultat(o)).namn) this-notationen är i denna metod onödig då du inte ger någon annan variabel men namnet namn som inparameter till metoden.

För övrigt misstänker jag att det kan ligga något fel i ditt sorteringsanropp prova att göra som Xaanin säger på den

Permalänk
Medlem
Skrivet av Vesh:

compareTo borde väl ta ett Object o som inparameter för att fungera?

Nej, eftersom han implementerar Comparable<Resultat> så förväntar sig compareTo ett Resultat-objekt.

Jag hade gjort något i denna stilen:

@Override public int compareTo(Result other) { if (this.time < other.time) return -1; if (this.time > other.time) return 1; return this.name.compareTo(other.name); }

Permalänk
Medlem

Kör med "bubble sort" istället? Kalla på den här metoden och skicka ArrayList av namnen samt tiderna som ligger i samma index som namnen.

private void Bubble_sort(ArrayList<Object> name/*löparnamn*/, ArrayList<Object> a/*tid*/) { int size = a.size(); int i, j, t = 0; Object temp = null; try { for (i = 0; i < size; i++) { for (j = 1; j < (size - i); j++) { if (Integer.parseInt(a.get(j - 1).toString()) > Integer.parseInt(a.get(j).toString())) { t = Integer.parseInt(a.get(j - 1).toString()); a.set(j - 1, a.get(j)); a.set(j, t); temp = name.get(j - 1); name.set(j - 1, name.get(j)); name.set(j, temp); } } } } catch (NumberFormatException e) { } }

Sedan kör du bara en loop för att skriva ut dom efter man sorterat namnen och tiderna samtidigt i metoden ovan:

for(int i = 0; i < name.size(); i++){ System.out.println("Runner: "+name.get(i)+" Time: "+time.get(i)); }

OJ ursäkta att jag inte läste färdigt ert inlägg.. Men hoppas du kanske kan få nytta av detta ändå.

Visa signatur

 MacBook Pro 15" Retina,  iPhone 6,  iPad Air,
Home server: AsRock q1900dc-itx, Bitfenix Prodigy, 4gb SO-DIMM DDR3L, 90w laptop charger, 2x2tb,