萝卜问题之我的OO解法
作者:互联网
原文链接:http://www.cnblogs.com/wangyh/archive/2009/06/04/radish-field-my-oo-solution.html
public class Cell
{
private static readonly int[][] offsetTable =
{
new[] {-1, -1}, new[] {0, -1}, new[] {1, -1},
new[] {-1, 0}, new[] {1, 0},
new[] {-1, 1}, new[] {0, 1}, new[] {1, 1},
};
private readonly int x;
private readonly int y;
private readonly int numOfRadish;
private readonly Field field;
public Cell(int x, int y, int numOfRadish, Field field)
{
this.x = x;
this.y = y;
this.numOfRadish = numOfRadish;
this.field = field;
}
public int NumOfRadish
{
get { return numOfRadish; }
}
public int GetSpecialNum()
{
int specialNum = 0;
foreach (int[] offset in offsetTable)
{
Cell cell = field.GetCell(offset[0] + x, offset[1] + y);
if (cell != null)
{
specialNum += cell.NumOfRadish;
}
}
return specialNum;
}
}
public class Field : IEnumerable<Cell>
{
private readonly int width;
private readonly int height;
private readonly Cell[,] field;
public Field(int width, int height)
{
this.width = width;
this.height = height;
field = new Cell[width,height];
}
public void AddCell(int x, int y, int numOfRadish)
{
field[x, y] = new Cell(x, y, numOfRadish, this);
}
public Cell GetCell(int x, int y)
{
if (x >= 0 && x < width && y >= 0 && y < height)
{
return field[x, y];
}
return null;
}
public IEnumerator<Cell> GetEnumerator()
{
foreach (Cell cell in field)
{
yield return cell;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
{
public static bool Between(this int value, int min, int max)
{
return min <= value && value <= max;
}
}
internal class Program
{
private static void Main(string[] args)
{
string[] testField = {
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890"
};
Console.WriteLine(CountSpecialNumbers(new[] {"111", "111", "111"}, 4, 8));
Console.WriteLine(CountSpecialNumbers(new[] {"111", "141", "111"}, 4, 8));
Console.WriteLine(CountSpecialNumbers(new[] {"2309", "0239", "2314"}, 5, 7));
Console.WriteLine(CountSpecialNumbers(new[] {"924", "231", "390", "910", "121"}, 31, 36));
Console.WriteLine(CountSpecialNumbers(new[] {"5"}, 3, 8));
Console.WriteLine(CountSpecialNumbers(testField, 3, 18));
}
public static int CountSpecialNumbers(string[] input, int A, int B)
{
Field field = GetField(input);
return field.Count(cell => cell.GetSpecialNum().Between(A, B));
}
private static Field GetField(string[] input)
{
Field field = new Field(input[0].Length, input.Length);
for (int line = 0; line < input.Length; line++)
{
string strLine = input[line];
for (int column = 0; column < strLine.Length; column++)
{
int numOfRadish = strLine[column] - '0';
field.AddCell(column, line, numOfRadish);
}
}
return field;
}
}
萝卜问题讨论的很多了,我就不再重复题目和要求了。我的OO解法对性能没有什么考虑,也没有在算法上有什么改进,主要目的有两个:1.用OO的方式表达,2.尽量使代码清晰易懂。当然了,世上不存在绝对好的代码,任何代码都有进一步改进的余地,所以如果觉得哪里可以进一步的改进,欢迎赐教。
Cell类,维护一个Cell本身的信息,包括他所在的行列坐标,格子里的萝卜数,以及计算它的特殊值。
public class Cell
{
private static readonly int[][] offsetTable =
{
new[] {-1, -1}, new[] {0, -1}, new[] {1, -1},
new[] {-1, 0}, new[] {1, 0},
new[] {-1, 1}, new[] {0, 1}, new[] {1, 1},
};
private readonly int x;
private readonly int y;
private readonly int numOfRadish;
private readonly Field field;
public Cell(int x, int y, int numOfRadish, Field field)
{
this.x = x;
this.y = y;
this.numOfRadish = numOfRadish;
this.field = field;
}
public int NumOfRadish
{
get { return numOfRadish; }
}
public int GetSpecialNum()
{
int specialNum = 0;
foreach (int[] offset in offsetTable)
{
Cell cell = field.GetCell(offset[0] + x, offset[1] + y);
if (cell != null)
{
specialNum += cell.NumOfRadish;
}
}
return specialNum;
}
}
Field类,维护Field本身的信息,包括行列数,以及所有的Cell。同时暴露接口设置Cell、获取Cell以及遍历所有的Cell。
Field.cspublic class Field : IEnumerable<Cell>
{
private readonly int width;
private readonly int height;
private readonly Cell[,] field;
public Field(int width, int height)
{
this.width = width;
this.height = height;
field = new Cell[width,height];
}
public void AddCell(int x, int y, int numOfRadish)
{
field[x, y] = new Cell(x, y, numOfRadish, this);
}
public Cell GetCell(int x, int y)
{
if (x >= 0 && x < width && y >= 0 && y < height)
{
return field[x, y];
}
return null;
}
public IEnumerator<Cell> GetEnumerator()
{
foreach (Cell cell in field)
{
yield return cell;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
Extension类,加了一个int的扩展方法Between
{
public static bool Between(this int value, int min, int max)
{
return min <= value && value <= max;
}
}
Program入口,初始化Field和Cell,计算并输出
Program.csinternal class Program
{
private static void Main(string[] args)
{
string[] testField = {
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890",
"1234567890"
};
Console.WriteLine(CountSpecialNumbers(new[] {"111", "111", "111"}, 4, 8));
Console.WriteLine(CountSpecialNumbers(new[] {"111", "141", "111"}, 4, 8));
Console.WriteLine(CountSpecialNumbers(new[] {"2309", "0239", "2314"}, 5, 7));
Console.WriteLine(CountSpecialNumbers(new[] {"924", "231", "390", "910", "121"}, 31, 36));
Console.WriteLine(CountSpecialNumbers(new[] {"5"}, 3, 8));
Console.WriteLine(CountSpecialNumbers(testField, 3, 18));
}
public static int CountSpecialNumbers(string[] input, int A, int B)
{
Field field = GetField(input);
return field.Count(cell => cell.GetSpecialNum().Between(A, B));
}
private static Field GetField(string[] input)
{
Field field = new Field(input[0].Length, input.Length);
for (int line = 0; line < input.Length; line++)
{
string strLine = input[line];
for (int column = 0; column < strLine.Length; column++)
{
int numOfRadish = strLine[column] - '0';
field.AddCell(column, line, numOfRadish);
}
}
return field;
}
}
Domain 的部分是Field和Cell,Program中处理输入和调用,由于Field实现了IEmumarable<T>接口, 可以使用LINQ做其他一些操作。每个方法代码量保持在10行或更少,易于理解。对于程序中的某些命名我还是不太满意,但是一时又想不出更好的名字了。
转载于:https://www.cnblogs.com/wangyh/archive/2009/06/04/radish-field-my-oo-solution.html
标签:OO,Field,int,萝卜,Cell,field,new,public,解法 来源: https://blog.csdn.net/weixin_30332705/article/details/96574248