Avatar billede lars66 Nybegynder
30. juli 2005 - 21:40 Der er 16 kommentarer og
1 løsning

Fjerne samme numre?

NrGener_1(){
      laver 10 tilfældige numre f.eks.:
      1,3,5,7,29,11,10,4,8,13
}

//kører igen:

NrGener_1(){
      laver 10 tilfældige numre f.eks.:
      1,9,5,30,21,12,17,4,36,13
}

Sorter-dubletter-fra(){
      (1,4,5,13)?
}

UdskrivTal(){
      udskriver tal (uden dubletter)
}

Hvis man generer nogle numre/tal i flere omgange, hvordan sorterer man så dubletterne fra?
Avatar billede arne_v Ekspert
30. juli 2005 - 21:48 #1
Du har 2 et-eller-andet (array/ArrayList) og dem merger du til 1 et-eller-andet.

Groft sagt er det vel 2 måder at mereg på:

1)  hver gang du flytter en over checker du først om den allerede er der

2)  du sorterer de 2 input så det er nemt at se duplikater mens du merger
Avatar billede arne_v Ekspert
30. juli 2005 - 22:29 #2
eksempel:

package july;

import java.util.Arrays;

public class Merger {
    public static void main(String[] args) {
        int[] a1 = { 1,3,5,7,29,11,10,4,8,13 };
        int[] a2 = { 1,9,5,30,21,12,17,4,36,13 };
        // test for already in
        int[] a12 = new int[a1.length + a2.length];
        int n = 0;
        for(int i = 0; i < a1.length; i++) {
            boolean alreadyin = false;
            for(int j = 0; j < n; j++) {
                if(a1[i] == a12[j])  {
                    alreadyin = true;
                    break;
                }
            }
            if(!alreadyin) {
                a12[n] = a1[i];
                n++;
            }
        }
        for(int i = 0; i < a2.length; i++) {
            boolean alreadyin = false;
            for(int j = 0; j < n; j++) {
                if(a2[i] == a12[j])  {
                    alreadyin = true;
                    break;
                }
            }
            if(!alreadyin) {
                a12[n] = a2[i];
                n++;
            }
        }
        for(int i = 0; i < n; i++) {
            System.out.print(" " + a12[i]);
        }
        System.out.println();
        // sort first and merge
        Arrays.sort(a1);
        Arrays.sort(a2);
        int[] a12x = new int[a1.length + a2.length];
        int nx = 0;
        int ix1 = 0;
        int ix2 = 0;
        while(ix1 < a1.length && ix2 < a2.length) {
            if(a1[ix1] == a2[ix2]) {
                a12x[nx] = a1[ix1];
                nx++;
                ix1++;
                ix2++;
            } else if(a1[ix1] < a2[ix2]) {
                a12x[nx] = a1[ix1];
                nx++;
                ix1++;
            } else {
                a12x[nx] = a2[ix2];
                nx++;
                ix2++;
            }
        }
        while(ix1 < a1.length) {
            a12x[nx] = a1[ix1];
            nx++;
            ix1++;
        }
        while(ix2 < a2.length) {
            a12x[nx] = a2[ix2];
            nx++;
            ix2++;
        }
        for(int i = 0; i < nx; i++) {
            System.out.print(" " + a12x[i]);
        }
        System.out.println();
    }
}
Avatar billede arne_v Ekspert
30. juli 2005 - 22:29 #3
Jeg er absolut ikke tilfreds med den kode - det burde kunne gøres pænere, men
jeg har ikke lige nogle gode ideer
Avatar billede erikjacobsen Ekspert
30. juli 2005 - 22:32 #4
Jeg har et andet syn på sagen, som måske (ikke) er som spørgeren ønsker. Men:

Hvis dine tilfældige tal skal ligge mellem 1 og 100, så lav et array med 100 indgang,
put tallene fra 1 til 100 ind i arrayet, og bland det så godt (det kan vi komme ind
på senere).

Nu kan du tage de 10 første tal ud. Og senere de 10 næste - og der er ingen dubletter.
Avatar billede simonvalter Praktikant
31. juli 2005 - 09:54 #5
Nu er der jo ingen der siger noget om at det skal være int og eller Integer så her er et andet forslag...det er langt fra så hurtigt som arne's sort first & merge og jeg går også ud fra at du mente int, men her kommer den aligevel.

Smid talene direkte i et Set eller SortedSet ;)
Avatar billede _carsten Nybegynder
31. juli 2005 - 10:02 #6
Så er vi næsten nødt til at have en mere.

Saml de to arrays til ét, sorter og lad være med at udskrive dubletter

import java.util.Arrays;

public class NrGener_1 {
   
    public NrGener_1() {
        ar1 = new int[]{1,3,5,7,29,11,10,4,8,13};
        ar2 = new int[]{1,9,5,30,21,12,17,4,36,13};
       
        result = new int[ ar1.length + ar2.length ];
       
        for(int i = 0; i < ar1.length;i++){
            result[i] = ar1[i];
        }
       
        for(int i = ar1.length ; i < (ar1.length + ar2.length);i++){
            result[i] = ar2[i - ar1.length];
        }
       
        Arrays.sort(result);

        int last = result[0] -1;
        int count = 0;
       
        for(int i = 0; i < result.length;i++){
            if(result[i] != last)
                System.out.println("" + result[i]);
            else
                count++;
            last = result[i];
        }
       
        System.out.println("Der var " + count + " dubletter, som ikke udskrives!");
    }
   
    public static void main(String[] args) {
        new NrGener_1();
    }
   
    private int[] ar1, ar2, result;
}
Avatar billede mikkelbm Nybegynder
31. juli 2005 - 10:10 #7
Og hvis din skal optimeres lidt, Carsten - så skal der vel bruges System.arraycopy, da jeg vil mene den er noget(meget) hurtigere end at løbe begge arrays igennem :)
Avatar billede _carsten Nybegynder
31. juli 2005 - 10:42 #8
Ja - den er købt. :)
Avatar billede simonvalter Praktikant
31. juli 2005 - 11:02 #9
Det er minimalt hvad System.arraycopy giver.. skulle op i 100000000 gennemløb før jeg kunne se en foreskel på 4 sekunder.
Arnes i iøvrigt stadig hurtigere ifølge mine microbenchmarks.. men den tager heller ikke højde for duplikater i samme array... det bliver vist heller ikke meget hurtigere.. har prøvet lidt med specielle sorterings algoritmer og optimerede libraries men det er mere til besvær end man får ud af det...  med Set og autoboxing bliver det ikke nemmere ;)
Avatar billede arne_v Ekspert
31. juli 2005 - 11:08 #10
merge sorted metoden kan ret nemt modificeres til at håndtere duplikater i samme array:

            if(nx == 0 || a1[ix1] > a12[nx-1]) {
                a12x[nx] = a1[ix1];
                nx++;
                ix1++;
            }

f.eks.

men jeg fandt det karakteristisk at der ikke var duplikater indenfor arrays
i de angivne data
Avatar billede mikkelbm Nybegynder
31. juli 2005 - 11:15 #11
Hvad jeg kender til System.arraycopy, så tager den referencerne fra de to arrays og smelter dem sammen på en eller anden måde (jeg tvivler på, at den metode løber dem igennem) - og det må da alt andet lige være noget hurtigere end lineært at løbe 2 arrays igennem. Men det kan godt være jeg tager fejl?
Avatar billede _carsten Nybegynder
31. juli 2005 - 11:21 #12
Kan det svare sig at begynde og optimere på de 2 x 10 gennemløb som jeg bruger ?

Fordelen og måske overskueligheden ved System.arraycopy() ligger vel i at det kan gøres på 2 linier, hvor jeg bruger 6 linier.

Kan dog sagtens følge tankegangen!
Avatar billede snoop_one Nybegynder
31. juli 2005 - 11:31 #13
Lige én til:
public static void main(String[] args) {
        Integer[] a1 = { 1, 3, 5, 7, 29, 11, 10, 4, 8, 13 };
        Integer[] a2 = { 1, 9, 5, 30, 21, 12, 17, 4, 36, 13 };
        Set<Integer> set = new HashSet<Integer>();
        set.addAll((Collection<? extends Integer>) Arrays.asList(a1));
        set.addAll((Collection<? extends Integer>) Arrays.asList(a2));
        for (Integer i : set) {
            System.out.println(i.intValue());
        }
}

____________________
Det er ikke den hurtigste metode, men bare for at vise et alternativ til de ellers mange gode forslag :0)
Avatar billede simonvalter Praktikant
31. juli 2005 - 12:21 #14
mikkel > her er lidt detaljer om System.arraycopy
3.4 http://www.usenix.org/events/vm04/tech/full_papers/grcevski/grcevski_html/
Avatar billede jesper2009 Nybegynder
01. august 2005 - 00:44 #15
Jeg vover endnu et bud. Jeg læser spørgsmålet sådan at der ikke kan være dubletter inde i de enkelte randomiserede talsekvenser men kun sekvenserne imellem (?). Jeg antager at sekvenserne har en øvre eller nedre grænse (her nedre):

int[] a = {1,3,5,7,29,11,10,4,8,13};
int[] b = {1,9,5,30,21,12,17,4,36,13};

int OUT_SIDE_RANGE = Integer.MIN_VALUE;
int duplicates = 0;

for(int i = 0; i < a.length; i++)
  for(int j = 0; j < b.length; j++)
    if(a[i] == b[j])
    {
      b[i] = OUT_SIDE_RANGE;
      duplicates++;
      break;
    }

int[] c = new int[a.length+b.length-duplicates];
System.arraycopy(a, 0, c, 0, a.length);
int cur = a.length;
for(int i = 0; i < b.length; i++)
  if(b[i] != Integer.MIN_VALUE)
    c[cur++] = b[i];
Avatar billede jesper2009 Nybegynder
01. august 2005 - 00:47 #16
Hov:
b[i] = OUT_SIDE_RANGE;
skulle være
b[j] = OUT_SIDE_RANGE;
Avatar billede arne_v Ekspert
03. september 2005 - 18:43 #17
lars>

tid at få afsluttet ?

og et svar fra mig
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