所以我有一个总是相同尺寸的矩阵,它的定义如下:
public void InitPositionsGrid()
{
int munberOfRows = 6;
for(int i = 0; i < munberOfRows; i++)
{
if( i % 2 == 0)
{
GridPositions[i] = new int[15];
}
else
{
GridPositions[i] = new int[14];
}
}
}
现在,我需要一种方法(递归或迭代的方式)填充该矩阵,但要使用特定的模式,以便在所有方向上均等地填充。该方法应采用3个参数(X和Y)来定义起始位置,以及另外一个要填充的位置数。应该看起来像这样:
public void FillGridMatrix(int startingRow, int startingColumn, int numberOfPlacesToFill)
{
//Fill the matrix with the following algorithm but don't go out of bounds
}
这是显示算法示例的图片:
想法是:从当前起始位置开始,检查“上方”两个空格(应为x-1,y-1和x-1,y),检查相邻的两个空格(x,y-1和x ,y + 1),最后检查“以下”两个空格(x + 1,y-1和x + 1,y)。坐标可能不完全是这些坐标,但这是一般的想法。请注意,当没有更多空间“上”或“下”时,要填充的位置应在左侧和右侧相等。起始行永远不能是第一行或最后一行。如果已经标记了当前正在检查的位置,请跳过该位置。可以填充的最大位数为87,矩阵本身中的最大元素数也可以为87。在第一轮之后,如果要填充的地方超过7个,则算法从左上角开始,并从起始位置(在本示例中为2和7)以右下角的“ adjacent”成员结束。
任何想法对此的最佳解决方案是什么?首选C#。
编辑:这是最接近我想要实现的解决方案,唯一的问题是这不适合递归,并且迭代解决方案需要太多条件。
public int PopulateMatrixAroundCertainPosition(int[][] matrix, int row, int column, int availableNumbers)
{
if(availableNumbers <= 0)
{
return 0;
}
matrix[row][column] = 1;
availableNumbers = PopulateSingleMatrixPosition(matrix, row - 1, column - 1, availableNumbers - 1);
availableNumbers = PopulateSingleMatrixPosition(matrix, row - 1, column, availableNumbers - 1);
availableNumbers = PopulateSingleMatrixPosition(matrix, row, column - 1, availableNumbers - 1);
availableNumbers = PopulateSingleMatrixPosition(matrix, row, column + 1, availableNumbers - 1);
availableNumbers = PopulateSingleMatrixPosition(matrix, row + 1, column - 1, availableNumbers - 1);
availableNumbers = PopulateSingleMatrixPosition(matrix, row + 1, column, availableNumbers - 1);
return availableNumbers - 1;
}
public int PopulateSingleMatrixPosition(int[][] matrix, int row, int column, int availableNumbers)
{
if (availableNumbers <= 0)
{
return 0;
}
if(matrix[row][column] == 1)
{
return availableNumbers + 1;
}
matrix[row][column] = 1;
return availableNumbers;
}
答案 0 :(得分:0)
无需递归。只是继续建立内部结构。我创建了一个小状态机来解决难题:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
const int TOTAL_BUTTONS = 61;
const int BUTTON_SIZE = 40;
const int SPACE = 10;
public Form1()
{
InitializeComponent();
BuildMatrix();
}
public enum LOCATION
{
TOP_ROW,
LEFT_BUTTON,
RIGHT_BUTTON,
BOTTOM_ROW
}
List<List<Button>> matrix = new List<List<Button>>();
int numberButtons = 0;
public void BuildMatrix()
{
int centerX = 0;
int centerY = 0;
int loopCounter = 1; //count of number of loops around matrix
int numberRows = 0;
int rowCount = 0;
int columnCount = 0;
centerX = this.Width / 2;
centerY = this.Height / 2;
LOCATION location = LOCATION.TOP_ROW;
List<Button> newRow = new List<Button>();
Button newButton = null;
Button buttonLeft = null;
for (int buttonCount = 0; buttonCount < TOTAL_BUTTONS; buttonCount++)
{
switch (location)
{
case LOCATION.TOP_ROW :
if (columnCount == 0)
{
newRow = new List<Button>();
if (numberRows++ == 0)
{
matrix.Add(newRow);
newButton = AddButton(centerY - (BUTTON_SIZE / 2), centerX - (BUTTON_SIZE / 2));
//add first button
newRow.Add(newButton);
loopCounter++;
continue;
}
else
{
matrix.Insert(0, newRow);
Button buttonDownRight = matrix[1][columnCount];
newButton = AddButton(buttonDownRight.Top - SPACE - BUTTON_SIZE, buttonDownRight.Left - ((SPACE + BUTTON_SIZE) / 2));
}
}
else
{
buttonLeft = matrix[rowCount][columnCount - 1];
newButton = AddButton(buttonLeft.Top, buttonLeft.Left + SPACE + BUTTON_SIZE);
}
//put new button above button below, move up one row, move left half column
newRow.Add(newButton);
if (++columnCount == loopCounter)
{
location = LOCATION.LEFT_BUTTON;
rowCount++;
}
break;
case LOCATION.LEFT_BUTTON :
Button buttonRight = matrix[rowCount][0];
newButton = AddButton(buttonRight.Top, buttonRight.Left - SPACE - BUTTON_SIZE);
matrix[rowCount].Insert(0, newButton);
location = LOCATION.RIGHT_BUTTON;
break;
case LOCATION.RIGHT_BUTTON :
buttonLeft = matrix[rowCount][matrix[rowCount].Count - 1];
newButton = AddButton(buttonLeft.Top, buttonLeft.Left + SPACE + BUTTON_SIZE);
matrix[rowCount].Add(newButton);
rowCount++;
if (rowCount >= numberRows)
{
location = LOCATION.BOTTOM_ROW;
}
else
{
location = LOCATION.LEFT_BUTTON;
}
columnCount = 0;
break;
case LOCATION.BOTTOM_ROW :
if (columnCount == 0)
{
newRow = new List<Button>();
matrix.Add(newRow);
numberRows++;
}
Button buttonTopLeft = matrix[rowCount - 1][columnCount];
newButton = AddButton(buttonTopLeft.Top + SPACE + BUTTON_SIZE, buttonTopLeft.Left + ((SPACE + BUTTON_SIZE) / 2));
matrix[rowCount].Add(newButton);
if (++columnCount == loopCounter)
{
location = LOCATION.TOP_ROW;
columnCount = 0;
rowCount = 0;
loopCounter++;
}
break;
}
}
}
public Button AddButton(int top, int left)
{
Button newButton = new Button();
newButton.Width = BUTTON_SIZE;
newButton.Height = BUTTON_SIZE;
newButton.Top = top ;
newButton.Left = left;
numberButtons++;
newButton.Text = numberButtons.ToString();
this.Controls.Add(newButton);
return newButton;
}
}
}