如何从数组中找到可能的k个元素集?

时间:2015-12-10 13:13:17

标签: c# .net recursion

我有一个数组{1,2,3,4,5,6,7,8,9,10},我必须找到来自array的k个元素的所有组合,而k将是动态的。因此,对于下面的4个元素,代码就足够了,但是我必须使用这个动态的方法,不确定将使用多少个for循环,所以请为此提出一些解决方案。

 for (i = 0; i < len - 3; i++)    
 {   
    for (j = i + 1; j < len - 2; j++)           
    {
       for (y = j + 1; y < len - 1; y++)              
       {                
          for (k = y + 1; k < len; k++)                    
          Console.WriteLine("{0},{1},{2},{3}", s[i], s[j],s[y], s[k]);             
       }                
    }
 }

3 个答案:

答案 0 :(得分:1)

您只需要用数组替换i, j, y, ...并手动展开for这样的循环

static void PrintCombinations(int[] input, int k)
{
    var indices = new int[k];
    for (int pos = 0, index = 0; ; index++)
    {
        if (index <= input.Length - k + pos)
        {
            indices[pos++] = index;
            if (pos < k) continue;
            // Consume the combination
            for (int i = 0; i < k; i++)
            {
                if (i > 0) Console.Write(",");
                Console.Write(input[indices[i]]);
            }
            Console.WriteLine();
            pos--;
        }
        else
        {
            if (pos == 0) break;
            index = indices[--pos];
        }
    }
}

答案 1 :(得分:1)

您可以使用此方法生成大小为l

的组合
div.get(0).getByXPath(".//div[@class='name']/a/text()")

您可以使用此方法生成大小为l的排列

public static List<List<T>> GenerateCombinations<T>(List<T> items, int l)
{
    if (l == 0)
        return new List<List<T>> { new List<T>() };

    var allCombs = new List<List<T>>();
    for (int i = 0; i < items.Count(); i++)
    {
        var listWithRemovedElement = new List<T>(items);
        listWithRemovedElement.RemoveRange(0, i + 1);

        foreach (var combination in GenerateCombinations(listWithRemovedElement, l - 1))
        {
            var comb = new List<T>(listWithRemovedElement.Count + 1);
            comb.Add(items[i]);
            comb.AddRange(combination);
            allCombs.Add(comb);
        }
    }
    return allCombs;
}

public static List<List<T>> GeneratePermutations<T>(List<T> items, int l) { if (l == 0) return new List<List<T>> { new List<T>() }; var allCombs = new List<List<T>>(); for (int i = 0; i < items.Count(); i++) { var listWithRemovedElement = new List<T>(items); listWithRemovedElement.RemoveAt(i); foreach (var combination in GeneratePermutations(listWithRemovedElement, l - 1)) { var comb = new List<T>(listWithRemovedElement.Count + 1); comb.Add(items[i]); comb.AddRange(combination); allCombs.Add(comb); } } return allCombs; } 的大小为2的排列

{ 1, 2, 3 }

var result = GeneratePermutations(new List<int>() { 1, 2, 3 }, 2); foreach (var perm in result) Console.WriteLine(string.Join(",", perm)); 1,2 1,3 2,1 2,3 3,1 3,2 的大小为2的组合

{ 1, 2, 3 }

答案 2 :(得分:0)

这不是我在现实生活中做的事情,但是因为这似乎是一个简单的家庭作业式问题,旨在让你使用递归和简单地写出组合的目的,这是一个相当简单的解决方案:

class Program
{
    public static void Main()
    {
        int[] test = { 1, 2, 3, 4, 5 };
        int k = 4;

        WriteCombinations(test, k);
        Console.ReadLine();
    }

    static void WriteCombinations(int[] array, int k, int startPos = 0, string prefix = "")
    {
        for (int i = startPos; i < array.Length - k + 1; i++)
        {
            if (k == 1)
            {
                Console.WriteLine("{0}, {1}", prefix, array[i]);
            }
            else
            {
                string newPrefix = array[i].ToString();
                if (prefix != "")
                {
                    newPrefix = string.Format("{0}, {1}", prefix, newPrefix);
                }
                WriteCombinations(array, k - 1, i + 1, newPrefix);
            }
        }
    }
}

如果可选参数不是&#34;基本&#34;够了,你可以拿掉默认值并在第一次调用时传递0"",或者你可以创建另一个&#34;包装器&#34;采用较少参数然后使用默认值调用第一个方法的方法。