0

Let say we have the fallowing classes 'X','Y','Z', The result so I need will be like this

(X),(X,Y),(X,Z),(X,Y,Z),(Y),(Y,Z),(Z)

And if we have 'X','Y','Z','J', The result so I need will be like this

(X), (X,Y),(X,Z),(X,J), (Y), (Y,Z),(Y,J), (Z),(Z,J)
(X,Y,Z), (X,Y,Z,J), (Y,Z,J), (Z,J,X)

What algorithm do I need to accomplish this?

Jon Lin
  • 142,182
  • 29
  • 220
  • 220
Yacov
  • 1,060
  • 14
  • 27
  • Are you talking about Classes? As in C# classes? I'm guessing not, but it's not clear from your question. Sounds a bit homeworky. – Cylindric May 01 '12 at 09:47
  • 1
    There are a few algorithms including implementations here: http://stackoverflow.com/questions/999050/most-elegant-way-to-get-all-subsets-of-an-array-in-c-sharp – kuba May 01 '12 at 09:49
  • Why are `(J)` and `(X, Y, Z)` not on your second list? – Eric Lippert May 01 '12 at 13:24
  • I guess so was forgotten... BTW: (X,Y,Z) exists on second list – Yacov May 01 '12 at 17:51

2 Answers2

7

What you are looking for is called a power set. There are both recursive and iterative ways to calculate it; it should not be difficult to google one.

Have a try at implementing an algorithm and come back to update the question if you have specific trouble.

Jon
  • 428,835
  • 81
  • 738
  • 806
2

If that is a power set, you missed out the empty set (which is always a member of a power set, of course!).

Anyway, something like this might work for you:

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

namespace Demo
{
    class Program
    {
        static void Main()
        {
            string[] classes = {"X", "Y", "Z"};

            foreach (var combination in PowerSet(classes))
            {
                foreach (var item in combination)
                {
                    Console.Write(item + ", ");
                }

                Console.WriteLine("");
            }
        }

        public static IEnumerable<IEnumerable<T>> PowerSet<T>(T[] sequence)
        {
            return from m in Enumerable.Range(0, 1 << sequence.Length)
                   select
                       from i in Enumerable.Range(0, sequence.Length)
                       where (m & (1 << i)) != 0
                       select sequence[i];
        }
    }
}

This algorithm works by "pretending" that the combinations are binary numbers. See http://en.wikipedia.org/wiki/Power_set for details (especially the section titled "Representing subsets as functions").

Matthew Watson
  • 104,400
  • 10
  • 158
  • 276