使用多态方法生成排列

时间:2015-05-06 02:07:31

标签: c# polymorphism permutation

说明:

  

请写一段代码作为输入列表   每个元素是另一个包含未知类型的列表   返回可以通过获取获得的所有可能列表的列表   每个输入列表中的一个元素。

     

例如:

     

[[1,2],[3,4]],应该返回:[[1,3],[1,4],[2,3],[2,4]]。

     

[['1'],['2'],['3','4']]应该返回[['1','2','3'],['1',   '2','4']。

我的代码:

     public void flipHorizontal (int x, int y, int size)

  {
    int half = size / 2;
    int x1 = x - half;
    int y1 = y - half;
    int x2 = x + half;
    int y2 = y + half;
    Pixel sourcePixel = getPixel (x1,y1);
    Pixel targetPixel = getPixel (x1, y1 + half);

    //loop through columns
    for (x = x; x < x2; x++)
    {
      //loop from 0 to before mirror point
      for (y = y; y < y2 + half; y++)
      {
        Color friend = sourcePixel.getColor();
        sourcePixel = getPixel (x1,y1);
        targetPixel = getPixel (x1, y1 + half);
        targetPixel.setColor (friend);
      }
    }
  }

我怎样才能使用返回通用列表的多态方法?

2 个答案:

答案 0 :(得分:3)

  

请写一段代码作为输入列表,其中每个元素是另一个包含未知类型的列表,并返回可以通过从每个输入列表中取一个元素获得的所有可能列表的列表

我会要求澄清,例如“你的意思是通用方法吗?”

在谈到多态时,他们很可能只能编写一个方法并将其称为任意类型,如:

public static IList<IList<T>> GetPermutations<T>(IList<IList<T>> inputLists) {
    if (inputLists.Count < 2) {
        // special case. 
    }

    return _permutationHelper(0, inputLists);
}

private static IList<IList<T>> _permutationHelper<T>(int i, IList<IList<T>> inputLists) {
    IList<IList<T>> returnValue = new List<IList<T>>();
    if (i == inputLists.Count) {
        returnValue.Add(new List<T>());
    } else {
        foreach (var t in inputLists[i]) {
            foreach (var list in _permutationHelper(i + 1, inputLists)) {
                list.Add(t);
                returnValue.Add(list);
            }
        }
    }

    return returnValue;
}

确实,您的实现在运行时允许任意类型,但它会失去类型安全性。鉴于它是C#中的一个实现,类型安全是一个要求是一个安全的猜测 - 但要求它也没有坏处。

另一件值得注意的事情 - 他们可能只是说他们正在寻找给定列表的Cartesian product

答案 1 :(得分:1)

我能想到的是,他们并没有尝试在列表中混合使用不同类型(就像你实现的那样),所有列表的类型都是相同的,他们希望你编写一个可以处理问题的通用类对于不同类型的列表,导致类似这样的事情:

static void Main(string[] args)
{
    var intCollections = new List<List<int>>();
    intCollections.Add(new List<int> { 1, 5, 3 });
    intCollections.Add(new List<int> { 7, 9 });

    var stringCollections = new List<List<String>>();
    stringCollections.Add(new List<String> { "a", "b" });
    stringCollections.Add(new List<String> { "c","d", "e" });
    stringCollections.Add(new List<String> { "g", "f" });

    //here you would have the "polymorphism", the same signature for different Lists types

    var intCombinations = GetPermutations(intCollections);
    var stringCombinations = GetPermutations(stringCollections);

    foreach (var result in intCombinations)
    {
        result.ForEach(item => Console.Write(item + " "));
        Console.WriteLine();
    }

    Console.WriteLine();

    foreach (var result in stringCombinations)
    {
        result.ForEach(item => Console.Write(item + " "));
        Console.WriteLine();
    }

    Console.WriteLine("Press any key to exit.");
    Console.ReadKey();
}

//This would be your generic implementation, basically changing from object to T and adding <T> after method

private static List<List<T>> GetPermutations<T>(List<List<T>> collections)
{
    List<List<T>> permutations = new List<List<T>>();

    //Check if the input list has any data, else return the empty list.
    if (collections.Count <= 0)
        return permutations;

    //Add the values of the first set to the empty List<List<object>>
    //permutations list
    foreach (var value in collections[0])
        permutations.Add(new List<T> { value });


    /* Skip the first set of List<List<object>> collections as it was
        * already added to the permutations list, and loop through the
        * remaining sets. For each set, call the AppendValues function
        * to append each value in the set to the permuations list.
        * */
    foreach (var set in collections.Skip(1))
        permutations = AppendNewValues(permutations, set);

    return permutations;
}

private static List<List<T>> AppendNewValues<T>(List<List<T>> permutations, List<T> set)
{
    //Loop through the values in the set and append them to each of the
    //list of permutations calculated so far.
    var newCombinations = from additional in set
                            from value in permutations
                            select new List<T>(value) { additional };

    return newCombinations.ToList();
} 

与您的通用实现相比,这种通用实现具有类型为Safety的优点,它确保您不会混合使用不同的对象类型。