C# 实现枚举所有满足条件的数组
现有一个 5×15 的数组, 第一列取值在1-15 ,第二列取值 16-30 第三列取值31-45 第四列 46-60 第五列取值61-75 ,要求5×15 的数组无重复数字意味着1-75的所有数字都要填充到这个数组里。 现在需要枚举所有满足这个条件的数组,而且要求任何两个数组之间没有相同号码的行。 比如 一个数组第一行为 5,17, 32,49 73 而另外一个数组第10行 也为 5,17,32,49,73 那么就认为后面生成的这个数组是无效的。
请各位高手帮给点意见。如何用C#实现,采用什么算法和数据结构比较好。 C#?算法? 算法 数据结构
[解决办法]
刚看清要枚举所有的,上边的方法就不行了。
要排序了。
算法就是将1-75这些数,填入一个数组,一共多少种填法。
用1于其他数交换;
在用2于其他数交换,
一直到75交换完
因为1于2交换和2与1交换是一样的,所有要去掉重复的
[解决办法]
才这么点数据,用for循环最快,其它都是浪费。
[解决办法]
根据题目的意思,先要做点组合数学的功课来优化最终的算法。
因为要求两个数组实例之间不能有行重复,经过一番考察,发现利用列的取数限制,可以将第一列固定并排序,然后后续的四列进行轮转和组合,这样所有可能的行被遍历并且不会被重复。最后对于15x5,共有15^4个数组。(一开始以为一部分要全排列,后来发现这样既麻烦又反而会引来重复)
using System;
using System.Text;
namespace Perm75
{
class Program
{
/// <summary>
/// A class that resolves the matrix puzzle (typically 15x5)
/// </summary>
class Perm15X5
{
#region Constructors
/// <summary>
/// Creates a Perm puzzle solver by given row and col numbers
/// </summary>
/// <param name="rows">The number of rows</param>
/// <param name="cols">The number of columns</param>
public Perm15X5(int rows = 15, int cols = 5)
{
_rows = rows;
_cols = cols;
Init();
}
#endregion
#region Methods
/// <summary>
/// Inits/resets the matrix
/// </summary>
private void Init()
{
// initializes the data
_indices = new int[_cols-1][]; // note row/col are transposed in this array
for (var i = 0; i < _cols-1; i++)
{
_indices[i] = new int[_rows];
for (var j = 0; j < _cols; j++)
{
_indices[i][j] = j;
}
}
_data = new int[_rows, _cols];
UpdateData();
}
/// <summary>
/// Get next matrix
/// </summary>
/// <returns>if available</returns>
public bool GetNext()
{
for (var curr = 0; curr < _cols - 1; curr++)
{
for (var i = 0; i < _rows; i++ )
{
_indices[curr][i] = (_indices[curr][i] + 1) % _rows;
}
if (_indices[curr][0] != 0)
{
UpdateData();
return true;
}
}
return false;
}
/// <summary>
/// Updates display data
/// </summary>
private void UpdateData()
{
for (var i = 0; i < _cols; i++)
{
var b = i * _rows + 1;
for (var j = 0; j < _rows; j++)
{
// the first row is always in ascending order
_data[j, i] = i == 0 ? b + j : b + _indices[i - 1][j];
}
}
}
/// <summary>
/// Returns its string representation
/// </summary>
/// <returns>string representation</returns>
public override string ToString()
{
var sb = new StringBuilder();
for (var i = 0; i < _cols; i++)
{
sb.AppendFormat("Row {0}: ", i);
for (var j = 0; j < _rows; j++)
{
sb.AppendFormat("{0:00} ", _data[j, i]);
}
sb.AppendLine();
}
return sb.ToString();
}
#endregion
#region Properties
private readonly int _rows;
private readonly int _cols;
private int[][] _indices;
private int[,] _data;
#endregion
}
/// <summary>
/// Program entry point
/// </summary>
static void Main()
{
var p = new Perm15X5();
var count = 0;
do
{
++count;
//Console.WriteLine("Instance {0}", count);
//Console.Write(p.ToString());
} while(p.GetNext());
Console.WriteLine("count = {0}", count);
}
}
}