encorez Juniormester
13. februar 2018 - 11:11 Der er 13 kommentarer og
1 løsning

Kombinere typer med forskellige antal værdier

Min udfordring er ikke JAVA afhængig, men det er Java jeg programmerer i.

Jeg har flere typer med forskellige antal værdier:
F.eks.
Type: Bil; værdier: 1,2,3,4
Type: Tog; Værdier: 5,6
Type: Cykel; Værdier: 5,6,97
Type: Fly; Værdier: 10

Udfordringen er at lave en funktionen som kan lave alle mulige kombinationer af værdierne, for 2 typer af gangen.
F.eks. at kombinere Bil og Fly vil give:
B1,F10
B1, B2, F10
B1, B2, B3, F10
B1, B2, B3, B4, F10
B2, F10
B2, B3, F10
B2, B3, B4, F10
B3, F10
osv

Nogle gode ideer?
sidwave Ekspert
13. februar 2018 - 13:32 #1
du kunne jo lave det så elegant, at biler er negative heltal, og fly positive ?
encorez Juniormester
13. februar 2018 - 15:14 #2
Men selv om jeg gør det, hvordan får jeg så lavet en funktion der gennemgår alle mulige kombinationer mellem alle værdierne i de to typer?
arne_v Ekspert
13. februar 2018 - 16:50 #3
Er antallet af typer fast?

Ja => 4 for loekker indeni hinanden

Nej => du skal bruge en rekursiv metode
encorez Juniormester
13. februar 2018 - 17:24 #4
Antallet af typer er fast ja, blot omkring 12-14. Men her skal jeg jo kun kombinere 2 af gangen.
Antallet af værdier er forskelligt fra type til type. For nogle typer er der 3 værdier, for andre 6, og for andre igen er der 12 værdier.
arne_v Ekspert
14. februar 2018 - 05:27 #5
Ah.

Saa noget a la:


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

public class Combi {
    public static class Type  {
        private String prefix;
        private int[] nos;
        public Type(String prefix, int... nos) {
            this.prefix = prefix;
            this.nos = nos;
        }
        public int length() {
            return nos.length;
        }
        public String getElement(int ix) {
            return prefix + nos[ix];
        }
        public List<String> getAllElements() {
            List<String> res = new ArrayList<String>();
            for(int i = 0; i < length(); i++) {
                res.add(getElement(i));
            }
            return res;
        }
    }
    private static void expand(List<String> base, List<String> a, int ix, List<List<String>> res ) {
        for(int i = ix; i < a.size(); i++) {
            List<String> newbase = new ArrayList<String>(base);
            newbase.add(a.get(i));
            res.add(newbase);
            expand(newbase, a, i + 1, res);
        }
    }
    private static List<List<String>> expand(Type typ) {
        List<List<String>> res = new ArrayList<List<String>>();
        List<String> a = typ.getAllElements();
        expand(new ArrayList<String>(), a, 0, res);
        return res;
    }
    private static String join(List<String> a1, List<String> a2) {
        StringBuilder sb = new StringBuilder();
        for(String s1 : a1) {
            sb.append("," + s1);
        }
        for(String s2 : a2) {
            sb.append("," + s2);
        }
        return sb.toString().substring(1);
    }
    public static void combine(Type typ1, Type typ2) {
        for(List<String> a1 : expand(typ1)) {
            for(List<String> a2 : expand(typ2)) {
                System.out.println(join(a1, a2));
            }
        }
    }
    public static void main(String[] args) {
        combine(new Type("B", 1, 2, 3, 4), new Type("F", 10));
    }
}
encorez Juniormester
20. februar 2018 - 21:14 #6
Hold da ferie, den virker perfekt :) Tusind tak.
encorez Juniormester
23. februar 2018 - 12:20 #7
Tillægsspørgmål, funktioner kombinerer værdier perfekt som de skal, men jeg sidder og nørder med at "fange" de værdi-kombinationer så jeg får dem returneret så jeg i en løkke kan arbejde med dem, kombination for kombination.

Kan funktionen "public static void combine(Type typ1, Type typ2) " returnere resultatet i et array eller lign?
arne_v Ekspert
23. februar 2018 - 14:57 #8
Det er nemt at generalisere.


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

public class Combi {
    @FunctionalInterface
    public static interface Handler {
        public void process(List<String> a1, List<String> a2);
    }
    public static class Type  {
        private String prefix;
        private int[] nos;
        public Type(String prefix, int... nos) {
            this.prefix = prefix;
            this.nos = nos;
        }
        public int length() {
            return nos.length;
        }
        public String getElement(int ix) {
            return prefix + nos[ix];
        }
        public List<String> getAllElements() {
            List<String> res = new ArrayList<String>();
            for(int i = 0; i < length(); i++) {
                res.add(getElement(i));
            }
            return res;
        }
    }
    private static void expand(List<String> base, List<String> a, int ix, List<List<String>> res ) {
        for(int i = ix; i < a.size(); i++) {
            List<String> newbase = new ArrayList<String>(base);
            newbase.add(a.get(i));
            res.add(newbase);
            expand(newbase, a, i + 1, res);
        }
    }
    private static List<List<String>> expand(Type typ) {
        List<List<String>> res = new ArrayList<List<String>>();
        List<String> a = typ.getAllElements();
        expand(new ArrayList<String>(), a, 0, res);
        return res;
    }
    public static void combine(Type typ1, Type typ2, Handler h) {
        for(List<String> a1 : expand(typ1)) {
            for(List<String> a2 : expand(typ2)) {
                h.process(a1, a2);
            }
        }
    }
}



import java.util.List;

import february.Combi.Type;

public class CombiDemo {
    private static String join(List<String> a1, List<String> a2) {
        StringBuilder sb = new StringBuilder();
        for(String s1 : a1) {
            sb.append("," + s1);
        }
        for(String s2 : a2) {
            sb.append("," + s2);
        }
        return sb.toString().substring(1);
    }
    private static void print(List<String> a1, List<String> a2) {
        System.out.println(join(a1, a2));
    }
    public static void main(String[] args) {
        Combi.combine(new Type("B", 1, 2, 3, 4), new Type("F", 10), CombiDemo::print);
    }
}
arne_v Ekspert
23. februar 2018 - 14:58 #9
Den printer naturligvis stadig.

Men du laver bar en:


private static void process(List<String> a1, List<String> a2) {
      // ...
}


der goer hvad du har brug for og sende den over som tredie argument.
arne_v Ekspert
23. februar 2018 - 15:05 #10
PS: Jeg har antaget at du er paa Java 8 eller nyere - det kan nemt omskrives til aeldre Java hvis noedvendigt.
encorez Juniormester
24. februar 2018 - 21:20 #11
Tusind tak :)
Jeg prøver at få de 2 classes til at virke og jeg får en fejl på "february" i linien "import february.Combi.Type;", kan du sige hvad der er galt der?
"february" er understreget og siger "cannot resolve symbol".

Jeg koder i IntelliJ IDEA og under "Project SDK" står der "1.8.0_131". Svarer det på om jeg bruger Java 8?
arne_v Ekspert
24. februar 2018 - 21:34 #12
Slet "february.". Jeg har klasserne i en package february, men jeg slettede den da jeg kopiered ind.
arne_v Ekspert
24. februar 2018 - 21:34 #13
Ja. Det er Java 1.8 alias Java 8 update (patch) level 131.
encorez Juniormester
24. februar 2018 - 21:43 #14
Ahhh, oki.

Jeg løste det ved at kopiere hele Combi-classen ind i CombiDemo.

Men jeg manglede stadig at få returneret resultatet til det sted hvor jeg kører "combine()", da det er der jeg skal bruges resultatet til at arbejde videre med.

Jeg lavede en
public static String kombistring = "";

Og denne
private static void print(List<String> a1, List<String> a2) {
        kombistring = kombistring + join(a1, a2)+";";
}

Og så efter min "combine" får jeg nu en variabel med resultatet som jeg kan arbejde videre med.
combine(new Type("B", 1, 2, 3, 4), new Type("F", 10), analyse_indicators2::print);
            System.out.println("kombistring:"+kombistring);


Tusind tak for hjælpen :)
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

Opret Preview

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





Premium
Kendt dansk trafik-app nægter at fjerne undersøgelse trods trussel om fogedforbud: "Den her undersøgelse bliver liggende, indtil der kommer en ny"
Interview: Saphe-stifter nægter at fjerne undersøgelse fra oktober 2017 fra tjenestens hjemmeside, men han erkender, at han ikke aner, hvordan det danske marked for trafik-apps forholder sig i dag. "Det kan være, at vi laver en ny undersøgelse på et tidspunkt, men den her undersøgelse bliver liggende, indtil der kommer en ny," lyder det.
CIO
Tag med på Computerworlds store lederkonference og mød de danske top-CIO'er, som bygger de nye it-afdelinger
Anvendelsen af digital teknologi og organiseringen af it-afdelinger er under radikal transformation. På konferencen Digitaliseringsledelse 2.0 kan du møde de CIO'er fra Bankdata, Adform og Rockwoll, som står i spidsen for teknologi-adoptionen.
Job & Karriere
Manden bag Stack Overflow til softwareudviklere og folk i it-branchen: Disse ting skal du lære, hvis du vil undgå at blive tromlet totalt
Interview: Manden bag Stack Overflow og Trello har en opsang til folk i it-branchen. Her er de kompetencer, som du bare skal tilegne dig nu.
White paper
Mobility - her er de aktuelle udfordringer
Hvad med sikkerheden? Mobility-bølgen fejer igennem danske virksomheder, og der er masser af muligheder og faldgruber. Sikkerheden halter, men det kan der gøres noget ved. Produceret af Computerworld.dk i oktober 2014.