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
Computerfans' paradis kæmper for livet: Nye nørder har indtaget Tokyos elektriske kvarter
Reportage: Tag med til Akihabara, der har været kendt som Tokyos elektriske bydel. Kvarterets gamle omdømme er under pres. De gamle boder med komponenter til selvbyggerne er kommet kraftigt i undertal, mens de nye nørder er rykket ind.
CIO
Allersidste opdatering på vej: Om en uge er det slut med stor-version af Windows 10 - skynd dig at opdatere
Om en uge er det slut for altid med den første store udgave af Windows 10, som Microsoft efter 29 måneder ikke længere vil supportere.
Job & Karriere
Vil strejkende it-folk kunne lægge hele Statens It ned? "Det har vi ingen kommentarer til," lyder den kryptiske melding fra Statens It
50 it-medarbejdere hos Statens It truer med at nedlægge arbejdet i sympatistrejke. Vil det betyde, at Statens It går ned?
Statens It nægter at svare.
White paper
Hvilken slags CRM understøtter bedst din forretning?
Hvordan vælger jeg det rigtige CRM-system? Hvad skal jeg prioritere? Denne guide giver dig et solidt grundlag for at vælge det CRM-system, der understøtter netop din virksomhed og jeres processer bedst – og som støtter op om arbejdet med bl.a. salg, marketing og service gennem den samlede kunderejse. Du får også konkrete og brugbare tips til, hvordan du øger sandsynligheden for, at CRM bliver en naturlig og selvfølgelig del af dine medarbejderes dagligdag. Hvilket jo er grundlaget for, at det samlede CRM-projekt bliver til en succes.