Avatar billede dk_zerocool Nybegynder
14. februar 2003 - 00:53 Der er 16 kommentarer og
3 løsninger

int array -> Integer Array

Jeg har et måske mærkeligt spørgsmål, som jeg håber at i kan besvare herinde.

Jeg har et klassesystem hvorfra jeg nedarver et array, også kaldet array, som indeholder et antal værdier som er genereret med (Math.Random). Arrayet skal sorteres med en alternativ Quicksort som jeg har fundet på nettet. Problemet ligger i at denne net-løsning bruger et Integer array som bla. sammenlignes med compareTo. Når jeg prøver at sætte mit array får jeg denne fejlbesked af compileren:

Så lyder spørgsmålet om jeg kan "caste" mit Integer Array til et int-array på en anden måde end (int).., eller er jeg helt forkert på den ??

--------------------------- Compiler Output ---------------------------
pQuicksort.java:17: inconvertible types

found  : int[]

required: int

        arr[i] = new Integer((int)(array));
Avatar billede disky Nybegynder
14. februar 2003 - 01:07 #1
Nu er det godt nok lidt sent, så jeg garantere ikke 100%.

Men jeg mener du må caste dem enkeltvis til den nye type.

Eventuelt kan du jo bare bruge den Indbyggede sort i Arrays.sort();
Avatar billede dk_zerocool Nybegynder
14. februar 2003 - 01:09 #2
Jeg søger en alternativ sorteringsalgoritme som er hurtigere end QuickSort og MergeSort, har du nogen forslag ??
Avatar billede dk_zerocool Nybegynder
14. februar 2003 - 01:10 #3
Hvis jeg skal caste dem enkeltvis, så skal jeg jo bruge en forløkke mere, og det tager jo farten af algoritmen...
Avatar billede dk_zerocool Nybegynder
14. februar 2003 - 01:12 #4
Sådan ser sammenhængen ud:

protected void sort() {
      Integer[] arr = new Integer[array.length];   

      for(i=0;i<array.length;i++){
//  Den oprindelige:    arr[i] = new Integer((int)(Math.random()));
        arr[i] = new Integer((int)(array));
      }
     
      qsort(arr);
    }
Avatar billede disky Nybegynder
14. februar 2003 - 01:13 #5
Det er korrekt det tager farten af algoritmen, men tidskomplexiteten er O(1) altså den er ligefrem propertional med antal elementer og derfor stadigvæk en hurtig routine.

Hvis du har et begrænset område tallene kan være indenfor ville jeg anvende en Bucketsort som er meget hurtig med en komplexitet på O(1);

Hvis du skal sortere alle tal imellem 1 og 10 laver du 10 spande, så tager du tallene en efter en, og tæller spanden med det rigtige nummer 1 op, osv.

f.eks. tallet 5 tæller spand #5 1 op osv.

bagefter løber du spandende igennem og udlæser antallet.

Så er det sorteret.

Ulempe ved f.eks. personnumre kræver det rigtigt mange spande, men er MEGET hurtig.
Avatar billede dk_zerocool Nybegynder
14. februar 2003 - 01:13 #6
Og jeg vil gerne helt af med forløkken, da arrayet bliver dannet i en anden klasse...derfor vil jeg caste arrayet (array) så jeg kan sætte den lige ind i qsort(array)..
Avatar billede disky Nybegynder
14. februar 2003 - 01:14 #7
din qsort() hvad type kræver den som parameter ?
Avatar billede dk_zerocool Nybegynder
14. februar 2003 - 01:14 #8
public static void qsort( Comparable[] c)
Avatar billede disky Nybegynder
14. februar 2003 - 01:15 #9
Så må du få metoden der generere data der skal sorteres til at lave dem om til Integers med det samme.
Avatar billede ulrikm Nybegynder
14. februar 2003 - 18:35 #10
Er O(1) ikke konstant tid? - det må være O(n). Det ville nok være smartest at lave qsort om til public static void qsort( int[] c ) - du kan bare lave din egen compareTo:

static int compareTo( int i1, int i2 )
{
  return i2 - i1; //eller omvendt?..
}

- og udskifte al brug af "Comparable" med "int".
Avatar billede arne_v Ekspert
14. februar 2003 - 20:47 #11
Der er ikke nogen generelle sorterings-algoritmer som er hurtigere end
quicksort, heapsort og mergesort der alle er n*log(n) algoritmer.

Og selvom heapsort har lidt bedre teoretiske egenskaber, så
viser mange års erfaring at quicksort er hurtigst.

Hvis du er interessert i hurtig sortering, så skal du ikke sortere
Integer[] men int[], da der er et markant overhead på at sortere
vilkårlige objekter.

Prøv og kør følgende program - det vil illustrere:

import java.util.Arrays;

public class SortTest {
    private final static int N = 1000000;
    public static void main(String[] args) {
        int[] ia = new int[N];
        Integer[] ioa = new Integer[N];
        for (int i = 0; i < N; i++) {
            ia[i] = (int) (Math.random() * N);
            ioa[i] = new Integer(ia[i]);
        }
        test1((int[]) ia.clone());
        test2((int[]) ia.clone());
        test3((Integer[]) ioa.clone());
        test4((Integer[]) ioa.clone());
    }
    public static void test1(int[] ia) {
        long t1 = System.currentTimeMillis();
        qsint(ia);
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < 10; i++)
            System.out.print(" " + ia[i]);
        System.out.println();
        System.out.println("int homemade QS : " + (t2 - t1));
        return;
    }
    public static void test2(int[] ia) {
        long t1 = System.currentTimeMillis();
        Arrays.sort(ia);
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < 10; i++)
            System.out.print(" " + ia[i]);
        System.out.println();
        System.out.println("int Java builtin sort: " + (t2 - t1));
        return;
    }
    public static void test3(Integer[] ioa) {
        long t1 = System.currentTimeMillis();
        qsobj(ioa);
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < 10; i++)
            System.out.print(" " + ioa[i]);
        System.out.println();
        System.out.println("Integer homemade QS : " + (t2 - t1));
        return;
    }
    public static void test4(Integer[] ioa) {
        long t1 = System.currentTimeMillis();
        Arrays.sort(ioa);
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < 10; i++)
            System.out.print(" " + ioa[i]);
        System.out.println();
        System.out.println("Integer Java builtin sort : " + (t2 - t1));
        return;
    }
    private static void qsint_help(int n1, int n2, int[] ia) {
        int tmp;
        int l = n1;
        int r = n2;
        int pivot = ia[(n1 + n2) / 2];
        do {
            while (ia[l] < pivot)
                l++;
            while (ia[r] > pivot)
                r--;
            if (l <= r) {
                tmp = ia[l];
                ia[l] = ia[r];
                ia[r] = tmp;
                l++;
                r--;
            }
        }
        while (l <= r);
        if (n1 < r)
            qsint_help(n1, r, ia);
        if (l < n2)
            qsint_help(l, n2, ia);
        return;
    }

    private static void qsint(int[] ia) {
        qsint_help(0, ia.length - 1, ia);
        return;
    }
    private static void qsobj_help(int n1, int n2, Comparable[] oa) {
        Comparable tmp;
        int l = n1;
        int r = n2;
        Comparable pivot = oa[(n1 + n2) / 2];
        do {
            while (oa[l].compareTo(pivot) < 0)
                l++;
            while (oa[r].compareTo(pivot) > 0)
                r--;
            if (l <= r) {
                tmp = oa[l];
                oa[l] = oa[r];
                oa[r] = tmp;
                l++;
                r--;
            }
        }
        while (l <= r);
        if (n1 < r)
            qsobj_help(n1, r, oa);
        if (l < n2)
            qsobj_help(l, n2, oa);
        return;
    }

    private static void qsobj(Comparable[] oa) {
        qsobj_help(0, oa.length - 1, oa);
        return;
    }
}

[SUN må iøvrigt have fundet et lille trick for objekt sorteringen - gad vide
om en af de andre algoritmer er hurtigere for objekter]
Avatar billede arne_v Ekspert
26. februar 2003 - 22:56 #12
zerocool>

Har du fået nogle svar du kunen bruge ?
Avatar billede dk_zerocool Nybegynder
27. februar 2003 - 12:17 #13
I fik hver 20 point for at prøve at løse problemet
Avatar billede disky Nybegynder
27. februar 2003 - 12:36 #14
ulrikm:
Jo du har ret det er O(n), quick sort har dog et problem, den kan ende om med O(n^2) hvis data ligger præcist omvendt af ønsket rækkefølge.
Avatar billede arne_v Ekspert
27. februar 2003 - 12:47 #15
disky>

Hvis man tager det første eller sidste element som pivot
element vil sorterede eller omvendt sorterede data
degenerere til O(n^2).

Derfor bør man altid tage midterste element som pivot element.

Der er selvfølgelig også nogle worst case rækkefølger for det, men
sandsyneligheden for at rende ind i dem er meget meget lille.
Avatar billede disky Nybegynder
27. februar 2003 - 13:40 #16
Der er mange måder at ødelægger quicksort på, men jeg går ud fra at metoden er korrekt implementeret.

Og hvis data er omvendt, tager det O(N^2) tid.
Avatar billede arne_v Ekspert
27. februar 2003 - 13:45 #17
Nej. Kun hvis man bruger første eller sidste element som pivot element.
Avatar billede nielsbrinch Nybegynder
06. oktober 2003 - 10:36 #18
Man kan ikke bare tage det midterste element og regne med at det er godt. Man kan sagtens være uheldig at det midterste element er eksempelvis det mindste. For at formindske chancen endnu mere, kan man tage det første, sidste og midterste tal og så vælge medianen af de 3 tal.
Avatar billede arne_v Ekspert
06. oktober 2003 - 10:54 #19
Der er ikke nogen der har påstået at det midterste tal er "godt".

Men det midterste tal har ikke problemer med data der er sorteret i forvejen.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester