c# - 如何从一维 int 数组返回数字网格?
问题描述
目前,我有一个一维整数数组,用于形成一个 9x9 的数字网格(但可以是任何大小)。我想输入一个索引并返回一个 3x3 的数字网格,有效地将 9x9 网格分解为 3x3 网格(想想数独)。
到目前为止,我已经尝试了两个嵌套循环,一个循环用于网格的高度,其中一个循环用于网格的宽度。但我无法让它与第一个 3x3 网格以外的任何东西一起工作,或者当尺寸从 9x9 变化时。
到目前为止我所拥有的:
int squareWidth = 3;
int squareHeight = 3;
int index = 0;
for (int i = 0; i < 3; i++)
{
for (int j = index; j < 3; j++)
{
Console.WriteLine(array[j]);
}
index+=9;
}
4x4 网格示例应返回一个 2x2 网格,但在一维数组中。
想象第一个 2x2 网格是 1,2,2,4。在索引 0、1、4、5 处找到的数字。
第二个 2x2 网格是 7,2,4,5。在索引 2、3、6、7 中找到的数字。
var gameboard = new int[] {
1, 2, 7, 2,
2, 4, 4, 5,
4, 2, 1, 3,
3, 1, 2, 2 };
GetByGrid(2);
应该返回
7,2,4,5
由于我输入 2GetByGrid()
应该返回 2x2 网格
GetByGrid(3);
应该返回
4,2,3,1
进一步澄清网格是如何分解的。这是一个带有四个 2x2 网格的 4x4 棋盘。一个 9x9 的棋盘将有 9 个 3x3 网格。
1,2 | 7,2
2,4 | 4,5
---------
4,2 | 1,3
3,1 | 2,2
解决方案
为什么不使用 OOP 并使用网格元素的索引器和返回子矩阵的方法创建一个游戏板类。像这样的东西:
class Program
{
static void Main(string[] args)
{
var game = new GameBoard(3);
// Fill the board with sequencial number (the index).
var index = 0;
for (int i = 0; i < game.SubGridCount; i++)
{
for (int j = 0; j < game.SubGridCount; j++)
{
game[i, j] = index++;
}
}
// game =
// +----------+----------+----------+
// | 0 1 2 | 3 4 5 | 6 7 8 |
// | 9 10 11 | 12 13 14 | 15 16 17 |
// | 18 19 20 | 21 22 23 | 24 25 26 |
// +----------+----------+----------+
// | 27 28 29 | 30 31 32 | 33 34 35 |
// | 36 37 38 | 39 40 41 | 42 43 44 |
// | 45 46 47 | 48 49 50 | 51 52 53 |
// +----------+----------+----------+
// | 54 55 56 | 57 58 59 | 60 61 62 |
// | 63 64 65 | 66 67 68 | 69 70 71 |
// | 72 73 74 | 75 76 77 | 78 79 80 |
// +----------+----------+----------+
var data = game.ToArray();
// [0,1,2,3,4,5...79,80]
var A11 = game.GetSubArray(0, 0);
// [0,1,2,9,10,11,18,19,20]
var A12 = game.GetSubArray(0, 1);
// [3,4,5,12,13,14,21,22,23]
var A13 = game.GetSubArray(0, 2);
// [6,7,8,15,16,17,24,25,25]
var A32 = game.GetSubArray(2, 1);
// [57,58,59,66,67,68,75,76,77]
// In the A23 subgrid, get the (3,1) element
var x2331 = game[1, 2, 2, 0];
// 51
}
}
GameBoard
定义为
public class GameBoard
{
public GameBoard(int subGridSize)
{
this.SubGridSize = subGridSize;
this.SubGridCount = subGridSize*subGridSize;
this.Elements = new int[subGridSize*subGridSize*subGridSize*subGridSize];
}
public int SubGridSize { get; }
public int SubGridCount { get; }
int[] Elements { get; }
public int this[int row, int col]
{
get => Elements[SubGridCount*row+col];
set => Elements[SubGridCount*row+col] = value;
}
public int this[int grid_row, int grid_col, int row, int col]
{
get => Elements[SubGridCount*(grid_row*SubGridSize+row) + grid_col*SubGridSize + col];
set => Elements[SubGridCount*(grid_row*SubGridSize+row) + grid_col*SubGridSize + col] = value;
}
// Make a copy of the elements
public int[] ToArray() => Elements.Clone() as int[];
public int[] GetSubArray(int grid_row, int grid_col)
{
var array = new int[SubGridCount];
for (int i = 0; i < SubGridSize; i++)
{
var first_element = SubGridCount * (grid_row*SubGridSize+i) + grid_col* SubGridSize;
for (int j = 0; j < SubGridSize; j++)
{
array[i*SubGridSize + j] = Elements[first_element +j];
}
}
return array;
}
}
未来的工作
为了获得更大的灵活性,您可以添加一个SubGrid
包含n×n
元素的类,这样您就可以拥有更多特定于子网格的方法。例如:
var S32 = game.GetSubGrid(2, 1);
Debug.WriteLine(S32.ToString());
// 57 58 59
// 66 67 68
// 75 76 77
使用定义
public class SubGrid
{
public SubGrid(int size)
{
this.Size = size;
this.Elements = new int[size*size];
}
public SubGrid(int size, int[] elements)
{
this.Size = size;
this.Elements = elements;
}
public int Size { get; }
public int[] Elements { get; }
public int this[int row, int col]
{
get => Elements[Size*row+col];
set => Elements[Size*row+col] = value;
}
public int[] ToArray() => Elements.Clone() as int[];
public override string ToString()
{
const int col_size = 3;
// print the grid
var sb = new StringBuilder();
for (int i = 0; i < Size; i++)
{
var row = Elements.Skip(i*Size).Take(Size);
sb.AppendLine(string.Join(" ", row.Select((x) => $"{x,-col_size}")));
}
return sb.ToString();
}
}
推荐阅读
- mysql - 带有连接的复杂 SQL
- c# - 如何使用 C# 读取正在运行的 Mono/Unity 游戏进程内存?
- ios - Firebase removeObserver 问题迅速
- javascript - 移动 JavaScript 下拉菜单未打开
- matlab - 如何使用两个 y 轴链接子图中的每个左右 y 轴
- php - Symfony 3.4 全局变量
- ruby-on-rails - 使用 wkhtmltopdf-binary 剪切文本
- apache-spark - Spark 数据集 - 引用类型为带有 callUDF 的数组的列
- c# - C#杀死不存在的进程
- webpack - 在 webpack 4 中,如何只在一个条目上拆分块?