sortowanie tablicy 2 wymiarowej

0

Witam

Próbuję posortować tablicę 2 wymiarową względem ostatniej kolumy z zachowaniem całego wiersza:

1.0 1.0 1.0
1.0 1.0 1.0
1.0 2.0 3.16
1.0 2.0 4.47
1.0 2.0 5.0
1.0 3.0 5.38
1.0 3.0 6.7
1.0 3.0 5.0
1.0 3.0 6.4

    public void Sortowanie(){
        for(int b=0;b<dane.length;b++){
        for(int a=0; a< dane.length-1; a++){
            double x = dane[a][2];
            double y = dane[a+1][2];
            if(x>y){
                dane[a][2] = y;
                dane[a+1][2] = x;
            }
        }}
    }

Nie działa to na razie dobrze, proszę o poradę ;-) Jak przepisać resztę wiersza.
Pozdrawiam

0

resztę wiersza możesz przepisać dokładnie tak samo (albo odrobinę prościej) jak ostatnią kolumnę - w tym samym ifie

0
    public void Sortowanie(){
        for(int b=0;b<dane.length;b++){
        for(int a=0; a< dane.length-1; a++){
            double x = dane[a][2];
            double y = dane[a+1][2];
            if(x>y){
                dane[a][2] = y;
                dane[a+1][2] = x;
                    for(int c = 0; c < dane[0].length-1; c++){
                        double p = dane[a][c];
                        double r = dane[a+1][c];
                            dane[a][c] = r;
                            dane[a+1][c] = p;
                    }
            }
        }
      }
    }

Nie jestem jeszcze pewny, czy to dobrze działa, sprawdzę ;-)
Wygladą, że dobrze.

Pozdrawiam

0

no mniej więcej tak, ale zamianę dwóch elementów można zrobić przy użyciu jednej zmiennej tymczasowej (o to mi chodziło przy "albo odrobinę prościej") :)

0

A poza tym w Javie tablica wielowymiarowa składa się po prostu z referencji do tablic o niższym wymiarze, a więc można podmieniać referencje. Przykład tutaj: http://www.ideone.com/RBM8x

Edit:
Pomyłka :) Wyciąłem pierwszą uwagę.

0

Dzięki, ciekawy przykład.

Pozdrawiam

0

Witam

Czyli wyglądałoby to mniej więcej tak:

     public void Sortowanie1(){
        for(int b=0;b<dane.length;b++){
        for(int a=0; a < dane.length-1; a++){
            double x = dane[a][2];
            double y = dane[a+1][2];
            if(x>y){
                double temp[] = dane[a];
                dane[a] = dane[a+1];
                dane[a+1] = temp;
            }
            }
        }
    }

Pozdrowienia

0

Wygląda prawie dobrze. Widzę, że używasz sortowania bąbelkowego, ale robisz n 2 sprawdzeń zamiast n 2 / 2.

Zobacz tutaj:
http://pl.wikipedia.org/wiki/Sortowanie_b%C4%85belkowe#Pseudokod
Tam z każdą pętlą przechodzisz coraz mniej elementów.

Tak czy siak sortowanie bąbelkowe jest najgorszym rodzajem sortowania i lepiej już nauczyć się sortowania przez wstawianie. Jest prawie tak samo proste, ale ma przynajmniej jakieś zalety, np szybkie działanie dla prawie posortowanych danych. Optymalnym sortowaniem byłoby coś pokroju hybrydy quicksorta i heapsorta albo mergesorta, ale to już jest znacznie trudniejsze.

0

Witam

Przez wstawianie:

 
public void SortowaniePrzezWstawianie(){
        for(int a = 1; a<dane.length;a++){
            int b = a;
            double element = dane[a][2];
            double temp[] = dane[a];
                while((b > 0) && (dane[b-1][2] > element)){
                    dane[b] = dane[b-1];
                    b--;
                }
            dane[b] = temp;
        }
    }

Pozdrawiam

0

Jeśli to dobrze działa to bardzo ładnie.

Nie wiem czy wiesz, ale Java udostępnia metody do sortowania.

Do sortowania tablic jest ta metoda:
http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#sort(T[], java.util.Comparator)

A tu tutorial:
http://download.oracle.com/javase/tutorial/collections/interfaces/order.html

Teraz możesz dla sportu klepnąć Comparatora i/ lub przerobić swój kod na kolekcje.

0

Witam

Jak przerobić tablicę 2 wymiarową na kolekcję?
Przez referencję dane[a] nie da rady.
Poproszę o jakiś sposób.

Pozdrawiam

0

Rozumiem, że Comparatora do tablic już klepnąłeś?

Tablice dwuwymiarowe można przerobić na takie dziwolągi jak kolekcję tablic czy tablicę kolekcji, ale lepiej po prostu użyć kolekcji kolekcji, czyli tutaj np listę list.

import java.util.ArrayList;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        List<List<Integer>> listaList = new ArrayList<List<Integer>>();
        for (int i = 0; i < 5; i++) {
            listaList.add(new ArrayList<Integer>());
        }
        listaList.get(5).add(8);
    }
}

Chociaż w twoim przypadku, jeżeli każdy wiersz ma z góry ustaloną, stałą ilość kolumn to może warto zrobić listę tablic? :)

0

Coś takiego by z tego wyszło:

 public void ArrayToList(){
        listaList.add(new ArrayList<Double>());
        for(int a =0;a<dane.length;a++){
            listaList.add(new ArrayList<Double>());
            for(int b=0;b<dane[0].length;b++){
                //listaList.add(new ArrayList<Double>());
                listaList.get(a).add(dane[a][b]);
            }
            //listaList.get(a).add(dane[a][0]);
        }
    }

Pozdrawiam

0

Za dużo masz tych List.add. Ten początkowy jest niepotrzebny.

W Javie niby jest metoda do konwersji tablic na listy: http://download.oracle.com/javase/6/docs/api/java/util/Arrays.html#asList(T...) , niestety nie potrafi skonwertować int[] na List<Integer>, co najwyżej Integer[] na List<Integer>. Autoboxing takich sytuacji nie obejmuje.

Tymczasem tablica intów to już nie jest typ podstawowy tylko klasa, a więc skonwertowanie tablicy tablic na listę tablic to jedno wywołanie funkcji:

import java.util.Arrays;
import java.util.List;

public class Main {

    public static void main(String[] args) {
        int tablicaTablic[][] = {
            {1, 2},
            {3, 4}
        };
        List<int[]> listaTablic = Arrays.asList(tablicaTablic);
        for (int[] rząd : listaTablic) {
            for (int liczba : rząd) {
                System.out.print(liczba + " ");
            }
            System.out.println();
        }
    }
}
0

Witam

Komparator do tablicy:

import java.util.Comparator;
public class Komparator implements Comparator{
            public int compare(Object o1, Object o2){
                double[] row1 = (double[])o1;
                double[] row2 = (double[])o2;
                if((row1[2]  - row2[2])<0)
                    return -1;
                else
                    return 1;
            }
} 

Pozdrawiam

ps. no teraz to już raczej z sortowaniem nie powinienem mieć problemów. Dziękuję bardzo ;-)

0

A gdzie parametryzacja? Powinno być: implements Comparator<double[]>. Poza tym powinieneś jeszcze przeciążyć metodę equals - tutaj dwa elementy są identyczne (tzn mają taką samą pozycję po posortowaniu), jeżeli trzecia kolumna zawiera tą samą liczbę.

ATSD:
Arrays.asList jest metodą sparametryzowaną, generalnie metody sparametryzowane to chyba jedyne miejsce gdzie odbywa się inferencja typów w Javie (!).

0

Witam

Nie jestem pewny, ale to byłoby coś takiego:

import java.util.Comparator;
public class KoparatorParam implements Comparator{
     int kolumna;
        KoparatorParam(int kolumna){
            this.kolumna = kolumna;
        }
        public int compare(Object o1, Object o2){
                double[] rzad1 = (double[])o1;
                double[] rzad2 = (double[])o2;
                if((rzad1[kolumna]  - rzad2[kolumna])<=0)
                    return -1;
                else
                    return 1;
            }
} 

Pozdrawiam

0

Przejrzyj sobie jakiś tutorial do genericsów, bo w ogóle ich nie używasz i pewnie nie rozumiesz, tutaj jest jakiś: java.sun.com/j2se/1.5/pdf/generics-tutorial.pdf

A kod powinien wyglądać mniej więcej tak:

import java.util.Comparator;

public class Komparator implements Comparator<double[]> {

    public int compare(double[] row1, double[] row2) {
        double diff = row1[2] - row2[2];
        if (diff < 0.) {
            return -1;
        } else if (diff == 0.) {
            return 0;
        } else {
            return 1;
        }
    }
}

1 użytkowników online, w tym zalogowanych: 0, gości: 1