Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 17:59 Der er 18 kommentarer og
1 løsning

finde alle mulige kombinationer af N tal

Hej

Jeg skal bruge en metode der gir mig alle mulige kombinationer.
Lad os sige jeg har tallene fra 1-10 , så vil jeg gerne have dem blandet så jeg får alle kombinationer.
Nogen der har en god ide til det ?

vh Brian
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 18:00 #1
hints eller ideer er også velkomne - kan godt kode C# , er bare lidt usikker på hvordan man skulle løse denne her på en smart måde. :)
Avatar billede arne_v Ekspert
27. oktober 2009 - 18:02 #2
Standard spoergsmaalene er:
- skal der traekked et fast antal tal eller et ethvert antal tal 1-10 ok ?
- betyder raekkefoelgen noget?
Avatar billede arne_v Ekspert
27. oktober 2009 - 18:06 #3
Jeg har kod etil det meste.

Her er et eksempel som genererer alle kombinationer af 4 ud af 16 tal hvor raekkefoelge ikke betyder noget:

using System;

namespace E
{
    public class MainClass
    {
        public delegate void Processor(int[] v);
        public static void Print(int[] v)
        {
            for(int i = 0; i < v.Length; i++) Console.Write(" " + v[i]);
            Console.WriteLine();
        }
        public static void Combinations(int[] a, int ix, int[] v, int used, Processor p)
        {
            if(used < v.Length)
            {
                for(int i = ix + 1; i < a.Length; i++)
                {
                    v[used] = a[i];
                    Combinations(a, i, v, used + 1, p);
                }
            }
            else
            {
                p(v);
            }
        }
        public static void Combinations(int[] a, int siz, Processor p)
        {
            Combinations(a, 0, new int[siz], 0, p);
        }
        public static void Main(string[] args)
        {
            int[] a = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
            Combinations(a, 4, Print);
        }
    }
}
Avatar billede Slettet bruger
27. oktober 2009 - 18:11 #4
Kan helt sikkert gøres mere elegant - men denne metode virker

for (a=0;a<10;a++)
  for (b=0;b<10;b++)
    for (c=0;c<10;c++)
      for (d=0;d<10;d++)
        for (e=0;e<10;e++)
          for (f=0;f<10;f++)
            for (g=0;g<10;g++)
              for (h=0;h<10;h++)
                for (i=0;i<10;i++)
                  for (j=0;j<10;j++)
tiTal = "|"+a+"|"+b+"|"+c+"|"+d+"|"+e+"|"+f+"|"+g+"|"+h+"|"+i+"|"+j+"|"
Avatar billede arne_v Ekspert
27. oktober 2009 - 18:15 #5
Ah. Hvis du kan genbruge det samme tal flere gange og raekkefoelgden betyder noget og du vil have 10 tal, saa er det en maade.

Det kan dog ogsaa laves med rekursion.
Avatar billede arne_v Ekspert
27. oktober 2009 - 18:21 #6
rekursiv kode:

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)
        {
            if(ix < a.Length)
            {
                for(int i = 0; i < a.Length; i++)
                {
                    Perm(a, p, prefix + " " + a[i], ix + 1);
                }
            }
            else
            {
                p(prefix);
            }
        }
        public static void Perm(int[] a, Process p)
        {
            Perm(a, p, "", 0);
        }
        public static void Main(string[] args)
        {
            Perm(new int[] { 1 }, delegate(string s) { Console.WriteLine(s); });
            Perm(new int[] { 1, 2 }, delegate(string s) { Console.WriteLine(s); });
            Perm(new int[] { 1, 2, 3 }, delegate(string s) { Console.WriteLine(s); });
            Console.ReadKey();
        }
    }
}
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 18:25 #7
Hej Arne , så godt det andet svar du gav i en lign sag , og har også prøvet din kode af - men det er ikke helt sådan det skal være :P

de 10 tal (kunne lige så godt være et andet , men vil højest sandsynligt være 10) - hvert tal må selvfølgelig kun optræde en gang og rækkefølgen er ligemeget, den kan jeg sortere på bagefter.

Det drejer sig i bund og grund om at jeg har to hold med 5 spillere på hvert hold og så skal jeg lave alle tænkelige muligheder.. - men anden del skulle jeg nok selv kunne lave.
Rækkenfølgen på holdet er ligegyldig og derfor skal jeg jo efterfølgende sortere en masse rækker ud da feks

spiller 1,2,3,4,5 vil være det samme som  1,3,4,2,5.

Håber det gav mening , og tak for den hurtige respons
Avatar billede arne_v Ekspert
27. oktober 2009 - 18:39 #8
Hm. Den er lidt mere tricky. Jeg proever lige at bixe noget.
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 18:41 #9
fedt :)
Avatar billede Slettet bruger
27. oktober 2009 - 18:51 #10
KISS:
<html><body><script>
for (a=1;a<10;a++)
  for (b=a+1;b<10;b++)
    for (c=b+1;c<10;c++)
/*    for (d=c+1;d<10;d++)
        for (e=d+1;e<10;e++)
          for (f=e+1;f<10;f++)
            for (g=f+1;g<10;g++)
              for (h=g+1;h<10;h++)
                for (i=h+1;i<10;i++)
                  for (j=i+1;j<10;j++)
*/
document.write("|"+a+"|"+b+"|"+c+"|<br>") // "+d+"|"+e+"|"+f+"|"+g+"|"+h+"|"+i+"|"+j+"|"

</script></body></html>
Avatar billede arne_v Ekspert
27. oktober 2009 - 19:16 #11
Forslag:

using System;
using System.Collections.Generic;
using System.Linq;

namespace E
{
    public class Combiner
    {
        public delegate void Process(string[] comb);
        private static void Combine(string[] elms, Process p, string[] comb, int start, int ix)
        {
            if(ix < elms.Length/2)
            {
                for(int i = start; i < elms.Length; i++)
                {
                    comb[ix] = elms[i];
                    Combine(elms, p, comb, i + 1, ix + 1);
                }
            }
            else
            {
                List<string> tmp = comb.ToList();
                tmp.AddRange(elms.Except(comb));
                if(comb[0] == elms[0]) // <---- delete if necesarry
                    p(tmp.ToArray());
            }
        }
        public static void Combine(string[] elms, Process p)
        {
            Combine(elms, p, new string[elms.Length/2], 0, 0);
        }
        private static void Print(string[] comb)
        {
            for(int i = 0; i < comb.Length; i++)
            {
                if(i == comb.Length/2)
                {
                    Console.Write(" - ");
                }
                else if(i > 0)
                {
                    Console.Write(" ");
                }
                Console.Write(comb[i]);
            }
            Console.WriteLine();
        }
        public static void Main(string[] args)
        {
            Combine(new string[] { "Alexander", "Benny", "Christian", "Dora", "Elin", "Frida" }, Print);
            Console.ReadKey();
        }
    }
}
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 19:33 #12
Hej

using System.Linq;

Bruger du den ?
Kører med framework 2..
Kan den laves uden link

får nemlig en fejl på

List<string> tmp = comb.ToList();
            tmp.AddRange(elms.Except(comb));

måske dumt spg, men Linq er da brugt i forbindelse med databaser ik ?
Avatar billede arne_v Ekspert
27. oktober 2009 - 19:39 #13
Jeg kan godt lave en .NET 2.0 loesning for de linier.

Jeg sprang bare over hvor gaerdet er lavest. Og det var LINQ.
Avatar billede arne_v Ekspert
27. oktober 2009 - 19:40 #14
MS har faaet rodet en masse sammen under begrebet LINQ:
- selve LINQ syntaxen i C# sproget
- et have af utility klasser og metoder i .NET frameworket
- O/R-mapperne LINQ for SQL og LINQ for EF som altsaa er database orienteret
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 19:42 #15
ahh okay , I see
Avatar billede arne_v Ekspert
27. oktober 2009 - 19:46 #16
Proev den her:

using System;
using System.Collections.Generic;

namespace E
{
    public class Combiner
    {
        public delegate void Process(string[] comb);
        private static void Combine(string[] elms, Process p, string[] comb, int start, int ix)
        {
            if(ix < elms.Length/2)
            {
                for(int i = start; i < elms.Length; i++)
                {
                    comb[ix] = elms[i];
                    Combine(elms, p, comb, i + 1, ix + 1);
                }
            }
            else
            {
               
                List<string> tmp = new List<string>(comb);
                tmp.AddRange(new List<string>(elms).FindAll(delegate(string s) { return !tmp.Contains(s); } ));
                if(comb[0] == elms[0]) // <---- delete if necesarry
                    p(tmp.ToArray());
            }
        }
        public static void Combine(string[] elms, Process p)
        {
            Combine(elms, p, new string[elms.Length/2], 0, 0);
        }
        private static void Print(string[] comb)
        {
            for(int i = 0; i < comb.Length; i++)
            {
                if(i == comb.Length/2)
                {
                    Console.Write(" - ");
                }
                else if(i > 0)
                {
                    Console.Write(" ");
                }
                Console.Write(comb[i]);
            }
            Console.WriteLine();
        }
        public static void Main(string[] args)
        {
            Combine(new string[] { "Alexander", "Benny", "Christian", "Dora", "Elin", "Frida" }, Print);
            Console.ReadKey();
        }
    }
}
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 19:55 #17
Arne sgu..

Du løser jo hele problemet for mig !! :P

Så vidt jeg kan se skal jeg ikke engang til at pille nogen linier ud , da der ik er nogen af dem der optræder mere end en gang , selv hvis man bytter rundt på rækkefølgen inden for det enkelte hold - har jeg ret ik ?

smid et svar , så får du points og kommer med i min aftenbøn :)
Avatar billede arne_v Ekspert
27. oktober 2009 - 20:05 #18
Hvis du sletter den linie jeg har markeret kommer der duplikat / omvendt hold ud af det (proev selv).

Jeg er ikke sikker paa at det er den mest optimale loesning, men det var lige hvad ideerne rakte til en tirsdag eftermiddag med graavejr.

Og et svar.
Avatar billede ghost1026 Nybegynder
27. oktober 2009 - 21:32 #19
den løsning ser okay optimal ud til mig , og den er hurtig.

Takker for den hurtige hjælp
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
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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