encorez Novice
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 Novice
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 Novice
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 Novice
20. februar 2018 - 21:14 #6
Hold da ferie, den virker perfekt :) Tusind tak.
encorez Novice
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 Novice
Skrevet i går kl. 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
Skrevet i går kl. 21:34 #12
Slet "february.". Jeg har klasserne i en package february, men jeg slettede den da jeg kopiered ind.
arne_v Ekspert
Skrevet i går kl. 21:34 #13
Ja. Det er Java 1.8 alias Java 8 update (patch) level 131.
encorez Novice
Skrevet i går kl. 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
Hjalp virksomheder Atea med at klage over omstridt udbud i Region Sjælland? Forsvarer udpeger Ib Kunøe som fællesnævner
Der indløb klager fra flere it-selskaber, da Region Sjælland i 2015 udpegede 3A-it som vinder af et stort it-udbud foran næsen af Atea. Det pudsige er, at klagerne var næsten ens. Forsvarer i Atea-sagen peger på et interessant sammenfald - Ib Kunøe.
Computerworld
Fona-ejer skal betale million-beløb tilbage: Hævede 22 millioner kroner lige inden krak
Fona-ejeren Elkjøp Nordic trak uretmæssigt 22 millioner kroner ud af selskabet lige inden salget af den kendte kæde gik ned med flaget.
CIO
Her er tre vigtige spørgsmål, som du altid bør stille til sælgere af it-systemer
Klumme: Softwareudviklere elsker at hade sælgere, der generelt er lidt for glatte, lidt for smilende, lidt for hjertelige og også dygtige til at undvige eller parere, når man fagligt argumenterer for sine forbehold overfor det system, man lige har fået præsenteret og lynhurtigt har spottet ikke vil fungere.
Job & Karriere
Regeringen vil gøre it-undervisning obligatorisk i folkeskolen: "Planen er, at alle danske børn skal lære at kode," siger undervisningsministeren
Interview: Regeringen indfører obligatorisk undervisning i it i folkeskolen på alle klassetrin og præsenterer fredag ny plan. Ny forsøgsordning i op til 50 skoler skal bane vejen. “Visionen for planen er, at alle danske børn skal lære at kode,” siger undervisningsminister Merete Riisager (LA).
White paper
Sådan vælger du business intelligence-løsning
I dette whitepaper undersøger vi, hvilke faktorer du skal være opmærksom på, når du vælger din kommende BI-løsning