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
Nyt Stig Abildsø-selskab er blevet Cisco-guldpartner på 17 måneder: "Det er i hvert fald danmarksrekord"
Interview: I september 2017 gik Wingmen Solutions på markedet. 17 måneder efter er selskabet guldpartner med Cisco. "Det er i hvert fald danmarksrekord," lyder det fra bestyrelsesformand Stig Abildsø, kendt fra netværksikonet Axcess.
Computerworld
SSD-priserne kollapser: De lynhurtige drev koster under det halve af, hvad de gjorde i 2018
Efter en periode med prisstigninger, falder priserne på de hurtige SSD-drev nu hastigt.
CIO
Tech fra Toppen: Det har CIO Mads Madsbjerg Hansen fra FLSmidth lært af flere års global it-konsolidering
Tech fra Toppen: Flere års arbejde har betydet en reduktion i antallet af it-systemer hos FLSmidth. Men processen har ikke været uden overraskelser. Hør hvad CIO Mads Madsbjerg Hansen har lært af den omfattende og globale proces.
Job & Karriere
Toke Kruse: Jeg spår, at humankapital i 2019 erstattes af it-kapital
I 2019 vil vi se en kæmpe udskiftning af ressourcer, hvorunder de menneskelige processer overtages af software, der gør os mennesker hurtigere og mere effektive. Betyder det store fyringsrunder? Måske.
White paper
Sådan gør du din forretning agil uden at komplicere netværkssikkerheden
Mange virksomheder er i gang med en form for digital transformation, i forhold til hvordan produkter og services bringes til markedet og i sidste ende levere værdi til kunderne. Men digital transformation bringer også kompleksitet med sig i forhold til dem der opererer netværket. I dette white paper kigger vi nærmere på, hvordan du laver en succesfuld transformation og gør dit netværk sikkert.