Wypisanie wszystkich podzbiorów

0

Witam

Mam tablicę którą traktuję jako zbiór. Zbiór ten jest 4-elementowy - {a,b,c,d}. Potrzebuję wyznaczyć wszystkie 3-elementowe podzbiory tego zbioru które zostaną wpisane w drugą tablice o wymiarze [4,3]
tj.

Tab[0,0] = a
Tab[0,1] = b
Tab[0,2] = c
Tab[1,0] = b
Tab[1,1] = c
Tab[1,2] = d

itd.

Będę bardzo wdzięczna za pomoc :)

0

wklej kod ktory masz

0
            int[] Dlugosci1 = { 1, 2, 3, 4 };
            int[,] Trojkaty = new int[4, 3];

            int x = 0;
            int y = 1;
            int z = 2;

            for (int i = 0; i < 4; i++)
            {
                for (int j = 0; j < 3; j++)
                {
                    if (i<=0)
                    {
                        Trojkaty[i, j] = Dlugosci1[x++];
                    }
                    
                    else if (i==1)
                    {
                        Trojkaty[i, j] = Dlugosci1[y++];
                    }

                    else if (i==2 && j<2)
                    {
                        Trojkaty[i, j] = Dlugosci1[z++];
                    }

                    else 
                    {
                        Trojkaty[2, 2] = Trojkaty[0, 0];
                        Trojkaty[3, 1] = Trojkaty[0, 0];
                        Trojkaty[3, 0] = Trojkaty[1, 2];
                        Trojkaty[3, 2] = Trojkaty[0, 1];
                    }

                    
                  
                }
            }

Po 3h walki poddałam się i rozpisałam to w if. Fatalanie to wygląda, na dodatek działa wyłącznie przy 4 elementowym zbiorze, a zależałoby mi na gotowym rozwiązaniu które samo wylicza nawet gdy zbiór ulegnie zmianie z 4 elementowego np. na 6.

0

https://stackoverflow.com/questions/728972/finding-all-the-subsets-of-a-set

Tam w pierwszej odpowiedzi jest fajnie wytłumaczone jak to zrobić rekursywnie.

0

Hej, pamiętam jak kiedyś nie potrafiłem poradzić sobie z podobnym zadaniem. Jest na to sprytna sztuczka, na początku nie bierzesz żadnego elementu [0,0,0,0] potem bierzesz tylko pierwszy [0,0,0,1] potem drugi [0,0,1,0] potem tylko drugi i pierwszy[0,0,1,1] itd. Tak się akuratnie składa że dokładnie w ten sposób są zapisane liczby całkowite w systemie binarnym. Zero to 0000 jeden to 0001, dwa to 0010 itd. Wszytko co musisz zrobić to przeliterować od zera do liczby możliwych kombinacji (`2^4), i wybrać elementy których pozycje odpowiadają pozycja bitów ustawionych na 1 dla danej iteracji.

    class Program
    {
        static void Main(string[] args)
        {
            foreach (var set in GetSubSets(new[] { 1, 2, 3, 4 })) 
            {
                Console.WriteLine(SetToString(set));
            }
            Console.ReadKey();
        }

        private static string SetToString<T>(T[] set) //T to dowolny typ
        {
            return "{" + string.Join("; ", set) + "}";
        }

        public static IEnumerable<T[]> GetSubSets<T>(T[] source) //T to dowolny typ
        {

            if (source.Length > 32)// int ma 32 bity
                throw new IndexOutOfRangeException("Source lenght must be smaller than 32");

            int subSetCount = (int)Math.Pow(2, source.Length); 
            int elementsCount = source.Length;

            for (int setOrderNo = 0; setOrderNo < subSetCount; setOrderNo++)
            {
                List<T> subSet = new List<T>(); // tym czasowo przechowuje set
                for (int i = 0; i < elementsCount; i++)
                {

                    if(((setOrderNo>>i)&1)!=0)  // sprawdza czy bit na pozycji i ==1
// >> przesuwa liczbe o i pozycji w lewo b100>>3 == 001
// & tworzy nową liczbe z dwóch tak ze na pozycjach gdzie chociaż jedna ma zero po połączeniu będzie zero 00101 & 01011 ==0001
                    {
                        subSet.Add(source[i]);
                    }
                }
               yield return subSet.ToArray(); //zwraca tablice zaraz po jej utworzeniu
            }
        }
    }

1 użytkowników online, w tym zalogowanych: 0, gości: 1