萝卜问题讨论的很多了,我就不再重复题目和要求了。我的OO解法对性能没有什么考虑,也没有在算法上有什么改进,主要目的有两个:1.用OO的方式表达,2.尽量使代码清晰易懂。当然了,世上不存在绝对好的代码,任何代码都有进一步改进的余地,所以如果觉得哪里可以进一步的改进,欢迎赐教。
Cell类,维护一个Cell本身的信息,包括他所在的行列坐标,格子里的萝卜数,以及计算它的特殊值。

Cell.cs
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.cs
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();
}
}
Extension类,加了一个int的扩展方法Between
public static class Extension

{
public static bool Between(this int value, int min, int max)

{
return min <= value && value <= max;
}
}
Program入口,初始化Field和Cell,计算并输出

Program.cs
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;
}
}Domain 的部分是Field和Cell,Program中处理输入和调用,由于Field实现了IEmumarable<T>接口, 可以使用LINQ做其他一些操作。每个方法代码量保持在10行或更少,易于理解。对于程序中的某些命名我还是不太满意,但是一时又想不出更好的名字了。
download code