如何编写逐行和列式排序的二进制矩阵/数组?

时间:2016-05-04 15:12:13

标签: c# matrix binary iterator logic

我正在尝试编写一个生成MxN二进制2D数组的迭代器,如下所示:

1 1 1 1 1 1 0 0
1 1 1 1 0 0 1 1
1 1 0 0 1 1 1 1
0 0 1 1 1 1 1 1

如果我们将每一行视为二进制,例如 11111100 ,每一行都从大到小排序。

如果我们将每列视为二进制,例如。 1110 ,每列都从大到小排序。

0的数量Z是固定的。

iterator.Next()应该是这个:

1 1 1 1 1 1 0 0
1 1 1 1 0 0 1 1
1 1 0 0 1 1 1 1
1 0 1 0 1 1 1 1

M,N,Z可以是任何合理的值。

问题是如果我对每一行进行迭代,那么很难处理每一列,反之亦然。

还应考虑时间复杂性。

1 个答案:

答案 0 :(得分:1)

这是我的第一个镜头,GetPossibleLines()方法并不是真正的高效。 但是,如果你解决第二个问题解决了自己:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Possible combinations with m=8, z=2");

        var possibleLines = GetPossibleLines(8, 2).ToArray();
        for (int i = 0; i < possibleLines.Length; i++)
        {
            for (int j = 0; j < possibleLines[i].Length; j++)
            {
                Console.Write(possibleLines[i][j] ? 1 : 0);
            }
            Console.WriteLine();
        }
        Console.WriteLine("------------------------------");
        Console.WriteLine("And the Matrices:");

        foreach (var matrix in GetMatrices(8,5,2))
        {
            for (int i = 0; i < matrix.Length; i++)
            {
                for (int j = 0; j < matrix[i].Length; j++)
                {
                    Console.Write(matrix[i][j] ? 1 : 0);
                }
                Console.WriteLine();
            }

            Console.WriteLine("------------------------------------");
        }

        Console.WriteLine("---------------End------------------");

    }

    private static IEnumerable<bool[][]> GetMatrices(int m, int n, int z)
    {
        var possibleLines = GetPossibleLines(m, z).ToArray();

        var lineCombinations = GetPossibleLines(possibleLines.Length, n).ToArray();
        for (int i = 0; i < lineCombinations.Length; i++)
        {
            int combinationIndex = 0;
            bool[][] result = new bool[n][];
            for (int j = 0; j < lineCombinations[i].Length; j++)
            {
                if (!lineCombinations[i][j])
                {
                    result[combinationIndex++]= possibleLines[j];
                }
            }
            yield return result;

        }
    }

    private static IEnumerable<bool[]> GetPossibleLines(int m, int z)
    {
        for (int i = 1; i < Math.Pow(2, m); i++)
        {
            var remainder = i;
            var remainingZ = z;
            bool[] result = new bool[m];
            for (int j = 0; j < m && remainingZ > -1; j++)
            {
                bool b = remainder % 2 == 1;
                result[j] = b;
                remainder /= 2;
                if (!b)
                {
                    remainingZ--;
                }
            }
            if (remainder == 0 && remainingZ == 0)
            {
                yield return result;
            }
        }
    }
}