Avatar billede albor Nybegynder
16. maj 2012 - 14:21 Der er 8 kommentarer og
1 løsning

alle mulige kombinationer af N tal

Hej. Jeg er igang med et lave et windows.form program i C# og har brug for at kunne komme frem til alle mulige kombinationer af N tal, hvor N er variabel.

som input har jeg:
int[] nodes //indeholder alle tal

og som output vil jeg gerne have:
list<int[]> kombinations //indeholder en liste med kombinationer af nodes

Hvis nodes = {1,2,5,7} skal resultatet være
1257 2157 5127 7125
1275 2175 5172 7152
1527 2717 5217 7215
1572 2571 5271 7151
1725 2751 5721 7512
1752 2715 5712 7521

Jeg har læst mig frem til at det ville være smart at kunne lave sådan et stykke kode med rekursion, men her er jeg ikke så stærk. Nedenfor har jeg copypasted min fejlagtige kode som inspiration:


List<int[]> kombinations = new List<int[]>();

private void Combine(int[] Nodes, int[] prefix, int tæller)
        {
            foreach (int test in Nodes)
            {
                string tjek = "notfound";

                for (int i = 0; i < tæller; i++)
                {
                    if (test == prefix[i])
                    {
                        tjek = "found";
                    }               
                }

                if (tjek == "notfound")
                {
                    prefix[tæller] = test;

                    if (tæller == Nodes.Length - 1)
                    {
                        kombinations.Add(prefix);
                    }
                    else
                    {
                        tæller++;
                        Combine(Nodes, prefix, tæller);
                    }                   
                }
            }
        }
Avatar billede albor Nybegynder
16. maj 2012 - 14:42 #1
Tilføjelse: int[] prefix er tom til at starte med og tæller starter med at være 0
Avatar billede heinzdmx Nybegynder
16. maj 2012 - 17:41 #2
Velkommen til Eksperten.

Jeg har ikke lige selv hoved til at løse din problemløsning lige nu, men vil gerne komme med nogle tips

ÆØÅ

Undgå så vidt muligt specialtegn i dine variabel navne da forskellige editore ikke altid kan håndtere dem grundet ASCII / UTF m.fl.

Betingelser

I din kode kan jeg se du bruger

string tjek = "notfound";

og så
tjek = found

og så tjekker på det.

Det er lang mere optimeret at bruge en bool - den kan have 2 værdier true eller false

  bool tjek = false;

  tjek = true;



Jeg ved godt det ikke besvare dit egentlige spørgsmål, men mente det var en god ting at vide.
Avatar billede albor Nybegynder
16. maj 2012 - 17:59 #3
Tak for den varme velkomst og tak for tips. Når der er noget kode som jeg ikke helt har styr på har jeg det med at få koden til at se mere overskuelig ud og det gør jeg bl.a. ved at lave de løsninger som du påpeger :) Jeg vil følge dit råd og lave et par justeringer når jeg forhåbentlig får koden til at fungere.

Er der andre som har et forslag til en løsning? Jeg så nogle tidligere lignende problemer som en vis arne_v havde løsninger på. Er han stadig aktiv på eksperten.dk?
Avatar billede heinzdmx Nybegynder
16. maj 2012 - 18:06 #4
Ifølge hans historik har han besvaret spørgsmål så sent som i dag så det må blive et ja :)
Avatar billede arne_v Ekspert
16. maj 2012 - 19:55 #5
mit forslag:

using System;

namespace E
{
    public class Program
    {
        public delegate void Process(string s);
        public static void Perm(int[] a, Process p, String prefix, int ix, bool[] used)
        {
            if(ix < a.Length)
            {
                for(int i = 0; i < a.Length; i++)
                {
                    if(!used[i])
                    {
                        used[i] = true;
                        Perm(a, p, prefix + " " + a[i], ix + 1, used);
                        used[i] = false;
                    }
                }
            }
            else
            {
                p(prefix);
            }
        }
        public static void Perm(int[] a, Process p)
        {
            bool[] used = new bool[a.Length];
            Perm(a, p, "", 0, used);
        }
        public static void Main(string[] args)
        {
            Perm(new int[] { 1, 2, 5, 7 }, delegate(string s) { Console.WriteLine(s); });
            Console.ReadKey();
        }
    }
}
Avatar billede albor Nybegynder
16. maj 2012 - 20:32 #6
Hej arne_v og tak for dit svar. Af hvad jeg kan se på din kode ser det ud som om du skriver alle resultater ud i consollen. Da jeg har med windows.form at gøre og senere skal bruge alle kombinationerne til videre udregning skal jeg gerne have dem gemt i en liste istedet for at gemme resultaterne i consollen. Resultatet kunne gemmmes i følgende:

List<int[]> kombinations = new List<int[]>();

Er det muligt at modificere dit eksempel så man ender op med en liste med int[] kombinationer?

Mange tak for hjælpen!
Avatar billede arne_v Ekspert
16. maj 2012 - 20:56 #7
Lav om paa delegate saa den gemmer i en List<String> fremfor at printe.

Og hvis den saa skal lave helt perfekt skal den aendres engang mere til at gemme i en List<int[]>, hvilket vil give lidt ekstra kode.
Avatar billede albor Nybegynder
17. maj 2012 - 14:49 #8
Nu har jeg fået redigeret koden og den virker 100% som den skal. Stort tak! hvordan giver man points ?
Avatar billede arne_v Ekspert
17. maj 2012 - 15:52 #9
jeg skal foerst smide et svar
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

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