问题陈述(我想在答案中收到的内容在最后指出)
任务是为用户提供所有可能的元素序列的列表,其中元素(其类型是我的枚举器(MyEnum))根据某个强制条件定位 - 以便将元素放在当前位置在序列中,前 2 个元素必须具有合适的值(为此我使用下面的myEnumAvailabilityDictionary)
用户的元素序列最终将在表单或控制台上显示为由序列的所有元素组成的字符串,用符号“ - ”分隔
现有工作代码说明
有一个枚举:
public enum MyEnum
{
nan,
I,
II,
III,
V,
X
}
有一个实用程序类 ( ProgressionsUtil .cs) 用于生成序列列表并以各种方式使用它们。它本身存储了一个静态库,其中填充了每个MyEnum值的可用位置列表(可用位置是一个由 2 个元素组成的数组(也是MyEnum类型),之后可能会有一个新的MyEnum,其中这些数组的列表):
Dictionary<MyEnum, List<MyEnum[]>> myEnumAvailabilityDictionary = new Dictionary<MyEnum, List<MyEnum[]>(){
{MyEnum.I, new List<MyEnum[]>() {new MyEnum[] {MyEnum.nan,MyEnum.nan}, new MyEnum[] {MyEnum.nan,MyEnum.I}, new MyEnum[] {MyEnum.I,MyEnum.II}, new MyEnum[] {MyEnum.II,MyEnum.III}}},
{MyEnum.II, new List<MyEnum[]>() {new MyEnum[] {MyEnum.nan,MyEnum.nan},new MyEnum[] {MyEnum.I,MyEnum.III},new MyEnum[] {MyEnum.I,MyEnum.I}, new MyEnum[] {MyEnum.I,MyEnum.II}}},
{MyEnum.III, new List<MyEnum[]>() {new MyEnum[] {MyEnum.nan,MyEnum.nan}, new MyEnum[] {MyEnum.II,MyEnum.II}, new MyEnum[] {MyEnum.V,MyEnum.X}, new MyEnum[] {MyEnum.V,MyEnum.X}}},
{MyEnum.V, new List<MyEnum[]>() {new MyEnum[] {MyEnum.nan,MyEnum.nan}, new MyEnum[] {MyEnum.nan,MyEnum.V}, new MyEnum[] {MyEnum.I,MyEnum.X}, new MyEnum[] {MyEnum.I,MyEnum.X}}},
{MyEnum.X, new List<MyEnum[]>() {new MyEnum[] {MyEnum.nan,MyEnum.nan}, new MyEnum[] {MyEnum.I,MyEnum.nan}, new MyEnum[] {MyEnum.nan,MyEnum.I}, new MyEnum[] {MyEnum.I,MyEnum.I}}}
}
(其实库要大很多,放不全的,这里我举个填充的例子)
这个类有方法:
根据 2 个已经存在的元素(即它们在它之前)获取可用元素(类型为MyEnum)的列表
private List<MyEnum> GetAvailableMyEnumsOnPoint(MyEnum prevEl1, MyEnum prevEl2)
{
List<MyEnum> availableMyEnumsOnPoint = new List<MyEnum>();
foreach (var pair in myEnumAvailabilityDictionary)
{
if (pair.Value.Any(x => x[0] == prevEl1 && x[1] == prevEl2))
{
availableMyEnumsOnPoint.Add(pair.Key);
}
}
return availableMyEnumsOnPoint;
}
根据 2 个已经存在的元素来检查成为下一个元素的可能性(即它们在它之前)
private bool AvailableLastMyEnum(MyEnum el, MyEnum prevEl1, MyEnum prevEl2)
{
List<MyEnum[]> availableLastMyEnums;
myEnumAvailabilityDictionary.TryGetValue(el, out availableLastMyEnums);
return availableLastMyEnums.Any(x => x[0] == prevEl1 && x[1] == prevEl2);
}
获取可能的序列列表(目前它仅适用于输入值 2-4 包括在内)
public List<MyEnum[]> GetMyEnumProgressions(int elementInProgressionsCount)
{
List<MyEnum[]> definedMyEnumProgressions = new List<MyEnum[]>();
List<MyEnum> myEnums1 = GetAvailableMyEnumsOnPoint(MyEnum.nan, MyEnum.nan);
foreach (MyEnum el1 in myEnums1)
{
List<MyEnum> myEnums2 = GetAvailableMyEnumsOnPoint(MyEnum.nan, el1);
foreach (MyEnum el2 in myEnums2)
{
if (elementInProgressionsCount == 2)
{
if (AvailableLastMyEnum(el1, el1, el2))
{
definedMyEnumProgressions.Add(new MyEnum[2] { el1, el2 });
}
}
else
{
List<MyEnum> myEnums3 = GetAvailableMyEnumsOnPoint(el1, el2);
foreach (MyEnum el3 in myEnums3)
{
if (elementInProgressionsCount == 3)
{
if (AvailableLastMyEnum(el1, el2, el3))
{
definedMyEnumProgressions.Add(new MyEnum[3] { el1, el2, el3 });
}
}
else
{
List<MyEnum> myEnums4 = GetAvailableMyEnumsOnPoint(el2, el3);
foreach (MyEnum el4 in myEnums4)
{
if (elementInProgressionsCount == 4)
{
if (AvailableLastMyEnum(el1, el3, el4))
{
definedMyEnumProgressions.Add(new MyEnum[4] { el1, el2, el3, el4 });
}
}
}
}
}
}
}
}
return definedMyEnumProgressions;
}
我期望收到什么回应?
如何重构极端方法(GetMyEnumProgressions),使其适用于从2到100(或更多)的输入值,同时比我的更小(我想过将一段代码分离成一个单独的方法并调用它递归,但我无法弄清楚如何做到这一点)。或者如何改变整个方法以获得更简洁(视觉上更少体积)和性能方面的最佳代码
完成任务的加速\优化(获取可能序列的列表)
关于重构类似示例和更复杂的东西的文献
这就是递归方法发挥作用的地方。我没有完全理解任务的本质,所以我只是在优化过程中尝试保存代码的行为,简化代码本身。
结果是这样的
您可以更清楚地看到任务的本质,因此如果我错过了某个地方或没有看到新的优化,您可以进一步完善它。